home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / System7 tools / Frontier / Frontier SDK 2.1 / Toolkits / Applet Toolkit / appletmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-09  |  79.8 KB  |  4,268 lines  |  [TEXT/KAHL]

  1.  
  2. /*© Copyright 1988-1992 UserLand Software, Inc.  All Rights Reserved.*/
  3.  
  4.  
  5. #include <GestaltEqu.h>
  6. #include <iac.h>
  7. #include <menusharing.h>
  8. #include "appletinternal.h"
  9. #include "appletmain.h"
  10. #include "appletmenu.h"
  11. #include "appletscrollbar.h"
  12. #include "appletabout.h"
  13. #include "appletmenuops.h"
  14. #include "appletresource.h"
  15.  
  16.  
  17. /*
  18. IAC messages implemented by the Applet Toolkit layer.
  19. */
  20.     #define alertdialogtoken    'alrt'
  21.     #define confirmdialogtoken    'cnfm'
  22.     #define askdialogtoken        'askd'
  23.         
  24.     #define enabledialogtoken    'enbd'
  25.     #define geterrorstringtoken    'gers'
  26.     
  27.     #define gettargettoken        'gtrg'
  28.     #define settargettoken         'strg'
  29.     
  30.     #define newwindowtoken         'nwin'
  31.     #define openwindowtoken        'owin'
  32.     #define closewindowtoken    'cwin'
  33.     #define savewindowtoken        'swin'
  34.     #define revertwindowtoken    'rwin'
  35.     #define movewindowtoken        'mwin'
  36.     #define printwindowtoken    'pwin'
  37.     #define selectwindowtoken    'xwin'
  38.     #define zoomwindowtoken        'zwin'
  39.     
  40.     #define getfilepathtoken    'gpth'
  41.     #define getwindowpostoken    'gwps'
  42.     #define madechangestoken    'chgs'
  43.  
  44.     #define getpicttoken        'gpic'
  45.     #define gettexttoken        'gtex'
  46.     #define putpicttoken        'ppic'
  47.     #define puttexttoken        'ptex'
  48.     #define selectalltoken        'sela'
  49.     #define haveselectiontoken    'hsel'
  50.     
  51.     #define countwindowstoken    'twin'
  52.     #define nthwindowtoken        'nthw'
  53.     #define quittoken            'quit'
  54.     
  55.     #define setfonttoken        'sfon'
  56.     #define setfontsizetoken    'sfsz'
  57.  
  58. /*
  59. new undocumented verbs
  60. */
  61.     #define getpagerecttoken    'gprc'
  62.     #define getwindowrecttoken    'gwrc'
  63.     #define getbinarytoken        'gbin'
  64.     #define putbinarytoken        'pbin'
  65.     #define scrollwindowtoken    'lwin'
  66.     #define perftesttoken         'perf'
  67.  
  68.     
  69.     
  70. /*
  71. for communication with the applet body code -- it has copies of all the globals,
  72. and pointers to the callback routines that define the applet.
  73. */
  74.     tyappletrecord app;
  75.  
  76. /*
  77. globals used by the window visiter.
  78. */
  79.     bigstring bsvisit;
  80.     short vnumvisit;
  81.     short x1, x2; /*two short registers for visit routines*/
  82.     hdlappwindow lastwindowvisited;
  83.     
  84.     
  85. /*
  86. flag to control whether the user is interacting, or we're responding to an
  87. interapplication message. the error string is saved -- to be accessed by the
  88. GetErrorString verb.
  89. */
  90.     boolean fldialogsenabled = true;
  91.     bigstring bserrorstring;
  92.     
  93.  
  94. /*
  95. set true if the last event was a keystroke and it was cmd-period.
  96. */
  97.     boolean flcmdperiod = false;
  98.     
  99.  
  100. /*
  101. for fast events, we need to store a pointer to our application heap, so any
  102. allocations we do happen in the right heap.
  103. */
  104.     static THz appletheapzone;
  105.  
  106.  
  107. typedef struct tydiskwindowinfo { /*saved on disk after the applet's data handle*/
  108.     
  109.     short versionnumber;
  110.     
  111.     Rect windowrect;
  112.     
  113.     short vertmin, vertmax, vertcurrent;
  114.     
  115.     short horizmin, horizmax, horizcurrent;
  116.     
  117.     diskfontstring defaultfontstring;
  118.     
  119.     short defaultsize;
  120.     
  121.     tyjustification defaultjustification;
  122.     
  123.     char waste [64]; /*room to grow*/
  124.     } tydiskwindowinfo;
  125.     
  126. EventRecord appletevent; /*the last event received by appletmain.c*/
  127.     
  128. boolean flexitmainloop = false;
  129.  
  130. #define nowindowerror 7 /*index into the verb error STR# list*/
  131. #define windowopenerror 8
  132. #define nopictcallbackerror 9
  133. #define notextcallbackerror 10
  134. #define noputtextcallbackerror 11
  135. #define noputpictcallbackerror 12
  136.  
  137.  
  138. bigstring bstargetwindowname; /*title of window that IAC verbs apply to*/
  139.  
  140. static boolean flcurrentlyactive = true; /*we start active, then get juggled*/
  141.  
  142.  
  143. #define jugglerEvt 15 /*a suspend/resume event from the OS to us*/
  144.  
  145. typedef struct tyjugglermessage {
  146.     
  147.     long eventtype: 8; /*bits 24 -- 31*/
  148.     
  149.     long reservedbits: 22; /*bits 2 -- 23*/
  150.     
  151.     long flconvertclipboard: 1; /*bit 1*/
  152.     
  153.     long flresume: 1; /*bit 0*/
  154.     } tyjugglermessage;
  155.     
  156.  
  157. #define displaydebug true
  158.  
  159. #define minwindowwidth 125
  160. #define minwindowheight 100
  161.  
  162.  
  163.  
  164. static void debugrect (Rect r) {
  165.  
  166.     if (displaydebug) {
  167.     
  168.         FillRect (&r, gray);
  169.         
  170.         FrameRect (&r);
  171.         }
  172.     } /*debugrect*/
  173.     
  174.     
  175. static void zzz (void) {
  176.     
  177.     bigstring bs;
  178.     Rect r = (**(**app.appwindow).hpalette).r;
  179.     
  180.     setstringlength (bs, 0);
  181.     
  182.     pushint (r.top, bs); pushstring ("\p, ", bs);
  183.     
  184.     pushint (r.left, bs); pushstring ("\p, ", bs);
  185.     
  186.     pushint (r.bottom, bs); pushstring ("\p, ", bs);
  187.     
  188.     pushint (r.right, bs); 
  189.     
  190.     DebugStr (bs);
  191.     } /*zzz*/
  192.     
  193.  
  194. void apperaserect (Rect r) {
  195.     
  196.     pushclip (r);
  197.     
  198.     (*app.eraserectcallback) (r);
  199.     
  200.     popclip ();
  201.     } /*apperaserect*/
  202.     
  203.     
  204. boolean appalert (bs) bigstring bs; {
  205.     
  206.     copystring (bs, bserrorstring);
  207.     
  208.     if (!fldialogsenabled)
  209.         return (true);
  210.         
  211.     return (alertdialog (bs));
  212.     } /*appalert*/
  213.     
  214.     
  215. boolean appconfirm (bs) bigstring bs; {
  216.     
  217.     copystring (bs, bserrorstring);
  218.     
  219.     if (!fldialogsenabled)
  220.         return (true);
  221.         
  222.     return (confirmdialog (bs));
  223.     } /*appconfirm*/
  224.     
  225.     
  226. boolean appask (bigstring prompt, bigstring answer) {
  227.     
  228.     copystring (prompt, bserrorstring);
  229.     
  230.     if (!fldialogsenabled)
  231.         return (true);
  232.         
  233.     return (askdialog (prompt, answer));
  234.     } /*appask*/
  235.     
  236.     
  237. void setselectionstyleinfo (tyselectioninfo *pselinfo, boolean flpack) {
  238.     
  239.     union {
  240.         
  241.         short fontstyle;
  242.         
  243.         struct {
  244.             
  245.             int extrabits: 7; /*highest-order 7 bits are unused*/
  246.             
  247.             boolean flsubscript: 1;
  248.             
  249.             boolean flsuperscript: 1;
  250.             
  251.             boolean flextended: 1; /*not currently used*/
  252.             
  253.             boolean flcondensed: 1;
  254.             
  255.             boolean flshadow: 1;
  256.             
  257.             boolean floutline: 1;
  258.             
  259.             boolean flunderline: 1;
  260.             
  261.             boolean flitalic: 1;
  262.             
  263.             boolean flbold: 1;
  264.             } stylebits;
  265.         } u;
  266.     
  267.     tyselectioninfo x = *pselinfo;
  268.     
  269.     if (flpack) {
  270.         
  271.         u.fontstyle = 0; /*clear all bits*/
  272.         
  273.         u.stylebits.flsubscript = x.flsubscript;
  274.         
  275.         u.stylebits.flsuperscript = x.flsuperscript;
  276.         
  277.         u.stylebits.flextended = x.flextended;
  278.         
  279.         u.stylebits.flcondensed = x.flcondensed;
  280.         
  281.         u.stylebits.flshadow = x.flshadow;
  282.         
  283.         u.stylebits.floutline = x.floutline;
  284.         
  285.         u.stylebits.flunderline = x.flunderline;
  286.         
  287.         u.stylebits.flitalic = x.flitalic;
  288.         
  289.         u.stylebits.flbold = x.flbold;
  290.         
  291.         x.fontstyle = u.fontstyle;
  292.         }
  293.     else {
  294.         u.fontstyle = x.fontstyle;
  295.         
  296.         x.flsubscript = bitboolean (u.stylebits.flsubscript);
  297.         
  298.         x.flsuperscript = bitboolean (u.stylebits.flsuperscript);
  299.         
  300.         x.flextended = bitboolean (u.stylebits.flextended);
  301.         
  302.         x.flcondensed = bitboolean (u.stylebits.flcondensed);
  303.         
  304.         x.flshadow = bitboolean (u.stylebits.flshadow);
  305.         
  306.         x.floutline = bitboolean (u.stylebits.floutline);
  307.         
  308.         x.flunderline = bitboolean (u.stylebits.flunderline);
  309.         
  310.         x.flitalic = bitboolean (u.stylebits.flitalic);
  311.         
  312.         x.flbold = bitboolean (u.stylebits.flbold);        
  313.         }
  314.     
  315.     *pselinfo = x;
  316.     } /*setselectionstyleinfo*/
  317.     
  318.         
  319. void drawappgrowicon (appwindow) hdlappwindow appwindow; {
  320.     
  321.     register WindowPtr w = (**appwindow).macwindow;
  322.     
  323.     if ((**appwindow).flprinting)
  324.         return;
  325.     
  326.     if (app.vertscroll && app.horizscroll) {
  327.         
  328.         DrawGrowIcon (w);
  329.         }
  330.     else {
  331.         register short width = 15;
  332.         Rect rport = (*w).portRect;
  333.         Rect rclip;
  334.         
  335.         rclip = rport;
  336.         
  337.         rclip.left = rclip.right - width;
  338.             
  339.         rclip.top = rclip.bottom - width;
  340.         
  341.         pushclip (rclip);
  342.         
  343.         DrawGrowIcon (w);
  344.         
  345.         popclip ();
  346.         }
  347.     } /*drawappgrowicon*/
  348.     
  349.  
  350. boolean apppushwindow (appwindow) hdlappwindow appwindow; {
  351.     
  352.     return (pushmacport ((**appwindow).macwindow));
  353.     } /*apppushwindow*/
  354.     
  355.  
  356. boolean apppopwindow (void) {
  357.     
  358.     return (popmacport ());
  359.     } /*apppopwindow*/
  360.     
  361.     
  362. boolean apppushorigin (void) {
  363.  
  364.     hdlappwindow ha = app.appwindow;
  365.     
  366.     if (ha != nil) {
  367.     
  368.         (**ha).originpushdepth++;
  369.         
  370.         if ((**ha).originpushdepth == 1) { 
  371.         
  372.             SetOrigin ((**ha).scrollorigin.h, (**ha).scrollorigin.v);
  373.         
  374.             OffsetRgn ((*(**ha).macwindow).clipRgn, (**ha).scrollorigin.h, (**ha).scrollorigin.v);
  375.             }
  376.         }
  377.     } /*apppushorigin*/
  378.     
  379.     
  380. boolean apppoporigin (void) {
  381.  
  382.     hdlappwindow ha = app.appwindow;
  383.     
  384.     if (ha != nil) {
  385.     
  386.         (**ha).originpushdepth--;
  387.     
  388.         if ((**ha).originpushdepth == 0) { 
  389.         
  390.             OffsetRgn ((*(**ha).macwindow).clipRgn, -(**ha).scrollorigin.h, -(**ha).scrollorigin.v);
  391.         
  392.             SetOrigin (0, 0);
  393.             }
  394.         }
  395.     } /*apppoporigin*/
  396.     
  397.     
  398. boolean apppushclip (Rect r) {
  399.  
  400.     /*
  401.     this front-end for pushclip respects the current settings of the origin. applets
  402.     should call this routine instead of calling the quickdraw.c routine.
  403.     */
  404.     
  405.     hdlappwindow ha = app.appwindow;
  406.     
  407.     pushclip (r);
  408.     
  409.     if ((**ha).originpushdepth > 0) 
  410.         OffsetRgn ((*(**ha).macwindow).clipRgn, -(**ha).scrollorigin.h, -(**ha).scrollorigin.v);
  411.     } /*apppushclip*/
  412.     
  413.     
  414. boolean apppopclip (void) {
  415.  
  416.     /*
  417.     this front-end for popclip respects the current settings of the origin. applets
  418.     should call this routine instead of calling the quickdraw.c routine.
  419.     */
  420.     
  421.     hdlappwindow ha = app.appwindow;
  422.     
  423.     popclip ();
  424.     
  425.     if ((**ha).originpushdepth > 0) 
  426.         OffsetRgn ((*(**ha).macwindow).clipRgn, -(**ha).scrollorigin.h, -(**ha).scrollorigin.v);
  427.     } /*apppopclip*/
  428.     
  429.     
  430. void appprecallback (void) {
  431.     
  432.     hdlappwindow ha = app.appwindow;
  433.     
  434.     if (ha != nil) {
  435.         
  436.         pushclip ((**ha).contentrect);
  437.             
  438.         apppushorigin ();
  439.         }
  440.     
  441.     (*app.setglobalscallback) (); /*app can copy from app.appdata, appwindow to its own globals*/
  442.     } /*appprecallback*/
  443.     
  444.     
  445. void apppostcallback (void) {
  446.     
  447.     hdlappwindow ha = app.appwindow;
  448.         
  449.     if (ha != nil) {
  450.     
  451.         apppoporigin ();
  452.     
  453.         popclip ();
  454.         }
  455.     } /*apppostcallback*/
  456.     
  457.     
  458. boolean appopenbitmap (r, appwindow) Rect r; hdlappwindow appwindow; {
  459.     
  460.     return (openbitmap (r, (**appwindow).macwindow));
  461.     } /*appopenbitmap*/
  462.     
  463.  
  464. boolean appclosebitmap (appwindow) hdlappwindow appwindow; {
  465.     
  466.     closebitmap ((**appwindow).macwindow);
  467.     
  468.     return (true);
  469.     } /*appclosebitmap*/
  470.     
  471.  
  472. void getappdata (w, appdata) WindowPtr w; Handle *appdata; {
  473.     
  474.     /*
  475.     a window's refcon field points to the appwindow record, which in turn 
  476.     points to the applet's data in the appdata field.
  477.     */
  478.     
  479.     register hdlappwindow ha = (hdlappwindow) (*(WindowPeek) w).refCon;
  480.     
  481.     if (ha == nil)
  482.         *appdata = nil;
  483.     else
  484.         *appdata = (**ha).appdata;
  485.     } /*getappdata*/
  486.     
  487.  
  488. static boolean getwindowrefcon (w, refcon) WindowPtr w; long *refcon; {
  489.     
  490.     /*
  491.     9/30/92 dmb: carefully ensure that the window is one that is being managed 
  492.     by the Applet Toolkit -- use a heuristic that makes sense -- see below.
  493.     
  494.     return false if a valid refon isn't extracted.
  495.     */
  496.     
  497.     register long x;
  498.     
  499.     *refcon = 0; /*default*/
  500.     
  501.     x = (*(WindowPeek) w).refCon;
  502.     
  503.     if (x == 0)
  504.         return (false);
  505.     
  506.     if (odd (x))
  507.         return (false);
  508.     
  509.     if (gethandlesize ((Handle) x) < sizeof (tyappwindow))
  510.         return (false);
  511.     
  512.     if ((**(hdlappwindow) x).macwindow != w) /*sensible heuristic to skip other people's windows*/
  513.         return (false);
  514.     
  515.     *refcon = x;
  516.     
  517.     return (true);
  518.     } /*getwindowrefcon*/
  519.  
  520.  
  521. void getappwindowtitle (appwindow, bs) hdlappwindow appwindow; bigstring bs; {
  522.     
  523.     if (appwindow == nil)
  524.         setstringlength (bs, 0);
  525.     else
  526.         GetWTitle ((**appwindow).macwindow, bs);
  527.     } /*selectappwindow*/
  528.     
  529.     
  530. void setappwindowtitle (appwindow, bs) hdlappwindow appwindow; bigstring bs; {
  531.     
  532.     SetWTitle ((**appwindow).macwindow, bs);
  533.     } /*setappwindowtitle*/
  534.     
  535.  
  536. void showappwindow (appwindow) hdlappwindow appwindow; {
  537.     
  538.     ShowWindow ((**appwindow).macwindow);
  539.     } /*showappwindow*/
  540.     
  541.     
  542. void selectappwindow (appwindow) hdlappwindow appwindow; {
  543.  
  544.     SelectWindow ((**appwindow).macwindow);
  545.     } /*selectappwindow*/
  546.     
  547.     
  548. void invalappwindow (appwindow, flerase) hdlappwindow appwindow; boolean flerase; {
  549.     
  550.     Rect r;
  551.     
  552.     pushmacport ((**appwindow).macwindow); 
  553.     
  554.     r = (**appwindow).windowrect;
  555.     
  556.     invalrect (r);
  557.     
  558.     if (flerase) 
  559.         apperaserect (r);
  560.         
  561.     popmacport ();
  562.     } /*invalappwindow*/
  563.     
  564.     
  565. void setappwindow (appwindow) hdlappwindow appwindow; {
  566.     
  567.     register hdlappwindow ha = appwindow;
  568.     
  569.     app.appwindow = ha;
  570.         
  571.     if (ha == nil) {
  572.         
  573.         app.appdata = nil;
  574.         }
  575.     else {
  576.         app.appdata = (**ha).appdata;
  577.         
  578.         (*app.setglobalscallback) (); /*app can copy from app.appdata to its own globals*/
  579.         
  580.         SetPort ((**ha).macwindow);
  581.         
  582.         ClipRect (&(**ha).contentrect);
  583.         }
  584.     } /*setappwindow*/
  585.     
  586.     
  587. boolean apprectneedsupdate (Rect r) {
  588.     
  589.     register WindowPtr w = (**app.appwindow).macwindow;
  590.     
  591.     return (RectInRgn (&r, (*w).visRgn));
  592.     } /*apprectneedsupdate*/
  593.     
  594.     
  595. void appinvalstatusseparator (void) {
  596.     
  597.     Rect r = (**app.appwindow).statusrect;
  598.     
  599.     r.top = r.bottom;
  600.     
  601.     r.bottom += 2;
  602.     
  603.     InvalRect (&r);
  604.     } /*appinvalstatusseparator*/
  605.     
  606.     
  607. void updateappwindow (appwindow) hdlappwindow appwindow; {
  608.     
  609.     /*
  610.     DW 4/24/92: reordered things for IOWA.
  611.     
  612.     DW 4/25/92: added updating of palette.
  613.     
  614.     DW 4/30/92: added pre-update callback to allow IOWA to inval all dirty objects.
  615.     */
  616.     
  617.     register hdlappwindow ha = appwindow;
  618.     register WindowPtr w = (**ha).macwindow;
  619.     Rect rwindow = (*w).portRect;
  620.     Rect rstatus = (**ha).statusrect;
  621.     
  622.     appprecallback ();
  623.     
  624.     (*app.preupdatecallback) ();
  625.     
  626.     apppostcallback ();
  627.         
  628.     BeginUpdate (w);
  629.     
  630.     setappwindow (ha);
  631.     
  632.     /*update the palette*/ {
  633.         
  634.         if (app.haspalette) {
  635.         
  636.             if (apprectneedsupdate ((**(**ha).hpalette).r)) {
  637.             
  638.                 pushclip (rwindow);
  639.             
  640.                 paletteupdate ((**ha).hpalette);
  641.         
  642.                 popclip ();
  643.                 }
  644.             }
  645.         }
  646.         
  647.     /*update the status area*/ {
  648.         
  649.         if (app.statuspixels > 0) { /*has a status area*/
  650.             
  651.             Rect r = rstatus;
  652.             
  653.             r.top = r.bottom;
  654.             
  655.             r.bottom += 4;
  656.             
  657.             if (apprectneedsupdate (r)) { /*draw the double separator line*/
  658.                 
  659.                 r.bottom -= 2;
  660.                 
  661.                 pushclip (rwindow);
  662.                 
  663.                 debugrect (r);
  664.                 
  665.                 apperaserect (r);
  666.                 
  667.                 MoveTo (r.left, r.top);
  668.         
  669.                 LineTo (r.right, r.top);
  670.                 
  671.                 MoveTo (r.left, r.bottom);
  672.         
  673.                 LineTo (r.right, r.bottom);
  674.                 
  675.                 popclip ();
  676.                 }
  677.                 
  678.             if (apprectneedsupdate (rstatus)) {
  679.             
  680.                 pushclip (rstatus);
  681.             
  682.                 (*app.updatestatuscallback) ();
  683.             
  684.                 popclip ();
  685.                 }
  686.             }
  687.         }
  688.         
  689.     /*let the applet update his stuff*/ {
  690.         
  691.         Rect rcontent = (**ha).contentrect;
  692.         
  693.         if (apprectneedsupdate (rcontent)) {
  694.             
  695.             appprecallback ();
  696.             
  697.             (**ha).updaterect = (**(*w).visRgn).rgnBBox;
  698.             
  699.             (*app.setglobalscallback) (); /*app can copy from app.appdata to its own globals*/
  700.             
  701.             (*app.updatecallback) ();
  702.             
  703.             apppostcallback ();
  704.             }
  705.         }
  706.         
  707.     /*update the grow icon, scrollbars*/ {
  708.     
  709.         pushclip (rwindow);
  710.         
  711.         drawappgrowicon (ha);
  712.  
  713.         updateappscrollbars (ha);
  714.         
  715.         popclip ();
  716.         }
  717.         
  718.     EndUpdate (w);
  719.     } /*updateappwindow*/
  720.     
  721.     
  722. void computewindowinfo (macwindow, appwindow) WindowPtr macwindow; hdlappwindow appwindow; {
  723.     
  724.     register WindowPtr w = macwindow;
  725.     register hdlappwindow ha = appwindow;
  726.     hdlpaletterecord hpal = (hdlpaletterecord) (**appwindow).hpalette;
  727.     Rect r, rcontent, rstatus, rpalette;
  728.     
  729.     (**ha).windowrect = r = (*w).portRect;
  730.     
  731.     rcontent = r;
  732.     
  733.     /*take out for scrollbars*/ {
  734.         
  735.         register short scrollbarwidth = getscrollbarwidth ();
  736.         
  737.         if (app.vertscroll)
  738.             rcontent.right -= scrollbarwidth - 1;
  739.         
  740.         if (app.horizscroll)
  741.             rcontent.bottom -= scrollbarwidth - 1;
  742.         }
  743.     
  744.     if (app.statuspixels > 0) /*has a status area*/
  745.         rcontent.top += app.statuspixels + 3; /*a 3-pixel line separates status & content*/
  746.     
  747.     if (app.haspalette) { /*has an icon palette*/
  748.         
  749.         rpalette = rcontent;
  750.         
  751.         rcontent.left += (**hpal).palettewidth;
  752.         
  753.         rpalette.right = rcontent.left;
  754.         }
  755.     else
  756.         zerorect (&rpalette);    
  757.     
  758.     (**ha).oldcontentrect = (**ha).contentrect;
  759.         
  760.     (**ha).contentrect = rcontent;
  761.     
  762.     if (app.haspalette) 
  763.         (**(**ha).hpalette).r = rpalette;
  764.     
  765.     rstatus = r; /*copy left, right, top*/
  766.     
  767.     rstatus.bottom = rstatus.top + app.statuspixels;
  768.     
  769.     (**ha).statusrect = rstatus;
  770.     
  771.     (**ha).windowvertpixels = r.bottom - r.top;
  772.     
  773.     (**ha).windowhorizpixels = r.right - r.left;
  774.     
  775.     (**ha).defaultfont = app.defaultfont;
  776.     
  777.     (**ha).defaultsize = app.defaultsize;
  778.     
  779.     (**ha).defaultstyle = app.defaultstyle;
  780.     
  781.     (**ha).defaultjustification = leftjustified;
  782.     
  783.     pushmacport (w);
  784.     
  785.     pushstyle ((**ha).defaultfont, (**ha).defaultsize, (**ha).defaultstyle);
  786.     
  787.     (**ha).fontheight = globalfontinfo.ascent + globalfontinfo.descent;
  788.     
  789.     popstyle ();
  790.     
  791.     popmacport ();
  792.     
  793.     (**ha).macwindow = w;
  794.     } /*computewindowinfo*/
  795.     
  796.  
  797. void getdesktoprect (hdlappwindow appwindow, Rect *rwindow) {
  798.     
  799.     register WindowPtr w = (**appwindow).macwindow;
  800.     
  801.     *rwindow = (*w).portRect;
  802.     
  803.     pushmacport (w);
  804.             
  805.     localtoglobalrect (rwindow);
  806.             
  807.     popmacport ();
  808.     } /*getdesktoprect*/
  809.     
  810.     
  811. void disposeappwindow (appwindow) hdlappwindow appwindow; {
  812.  
  813.     register hdlappwindow ha = app.appwindow;
  814.     
  815.     (*app.disposerecordcallback) ();
  816.     
  817.     if (app.haspalette) 
  818.         disposepalette ((hdlpaletterecord) (**ha).hpalette);
  819.     
  820.     disposescrollbar ((**ha).vertbar);
  821.     
  822.     disposescrollbar ((**ha).horizbar);
  823.     
  824.     DisposeWindow ((**ha).macwindow);
  825.     
  826.     disposehandle ((Handle) ha);
  827.     
  828.     setfrontglobals ();
  829.     } /*disposeappwindow*/
  830.     
  831.  
  832. typedef boolean (*tyvisitapproutine) (hdlappwindow);
  833.  
  834.  
  835. boolean visitappwindows (visitproc) tyvisitapproutine visitproc; {
  836.     
  837.     /*
  838.     visit all the windows from front to back.  call the visitproc for each window, 
  839.     if it returns false we stop the traversal and return false.
  840.     
  841.     the visitproc takes one parameter -- a window pointer, indicating the window
  842.     to be visited.
  843.     
  844.     return true if all the visits returned true.
  845.     
  846.     9/4/91 DW: add lastwindowvisited -- returns nil if no match found, returns
  847.     pointing to the appwindow record for the window that matched the visitproc's
  848.     criteria.
  849.     
  850.     5/24/92 DW: skip windows that obviously aren't being managed by the Applet
  851.     Toolkit -- use a heuristic that makes sense -- see getwindowrefcon.
  852.     */
  853.     
  854.     register WindowPtr w = FrontWindow ();
  855.     hdlappwindow appwindow;
  856.     
  857.     lastwindowvisited = nil;
  858.     
  859.     while (w != nil) {
  860.         
  861.         if (!getwindowrefcon (w, (long *) &appwindow))
  862.             goto next;
  863.         
  864.         if (!(*visitproc) (appwindow)) { /*stop the traversal*/
  865.         
  866.             lastwindowvisited = appwindow; /*set global*/
  867.             
  868.             return (false);
  869.             }
  870.         
  871.         next:
  872.         
  873.         w = (WindowPtr) (*(WindowPeek) w).nextWindow; 
  874.         } /*while*/
  875.         
  876.     return (true); /*completed the traversal*/
  877.     } /*visitappwindows*/
  878.     
  879.  
  880. boolean selectvisit (appwindow) hdlappwindow appwindow; {
  881.     
  882.     bigstring bs;
  883.     
  884.     getappwindowtitle (appwindow, bs);
  885.     
  886.     if (!equalstrings (bsvisit, bs)) /*no match -- keep traversing*/
  887.         return (true);
  888.     
  889.     /*found a match, select the window, stop the traversal*/
  890.     
  891.     selectappwindow (appwindow);
  892.         
  893.     return (false); /*stop the traversal*/
  894.     } /*selectvisit*/
  895.     
  896.     
  897. boolean selectwindowbytitle (bs) bigstring bs; {
  898.  
  899.     /*
  900.     visit all the windows from front to back.  when we encounter one of the 
  901.     app's windows check the window title.  if it equals bs, then select the 
  902.     window and set the globals accordingly.
  903.     
  904.     return false if there is no app window with that name.
  905.     */
  906.     
  907.     copystring (bs, bsvisit); /*copy into global so visit routine can access*/
  908.     
  909.     return (!visitappwindows (&selectvisit));
  910.     } /*selectwindowbytitle*/    
  911.     
  912.     
  913. boolean findbytitlevisit (appwindow) hdlappwindow appwindow; {
  914.     
  915.     bigstring bs;
  916.     
  917.     getappwindowtitle (appwindow, bs);
  918.     
  919.     if (!equalstrings (bsvisit, bs)) /*no match -- keep traversing*/
  920.         return (true);
  921.     
  922.     return (false); /*stop the traversal*/
  923.     } /*findbytitlevisit*/
  924.     
  925.     
  926. boolean findbywindowtitle (bstitle, appwindow) bigstring bstitle; hdlappwindow *appwindow; {
  927.  
  928.     copystring (bstitle, bsvisit); /*copy into global so visit routine can access*/
  929.     
  930.     visitappwindows (&findbytitlevisit);
  931.     
  932.     if (lastwindowvisited == nil)
  933.         return (false);
  934.         
  935.     *appwindow = lastwindowvisited;
  936.     
  937.     return (true);
  938.     } /*findbywindowtitle*/
  939.     
  940.     
  941. boolean findnthvisit (appwindow) hdlappwindow appwindow; {
  942.     
  943.     return (++x2 < x1); /*visit until they're equal*/
  944.     } /*findnthvisit*/
  945.     
  946.     
  947. boolean findnthwindow (n, appwindow) short n; hdlappwindow *appwindow; {
  948.     
  949.     x1 = n; /*copy into a "register" for visit routine*/
  950.     
  951.     x2 = 0; /*another register*/
  952.     
  953.     visitappwindows (&findnthvisit);
  954.     
  955.     *appwindow = lastwindowvisited;
  956.     
  957.     return (lastwindowvisited != nil);
  958.     } /*findbywindowtitle*/
  959.     
  960.     
  961. boolean countwindowsvisit (appwindow) hdlappwindow appwindow; {
  962.     
  963.     x1++;
  964.     
  965.     return (true); /*keep going*/
  966.     } /*countwindowsvisit*/
  967.     
  968.     
  969. short countwindows (void) {
  970.     
  971.     x1 = 0; /*copy into a "register" for visit routine*/
  972.     
  973.     visitappwindows (&countwindowsvisit);
  974.     
  975.     return (x1);
  976.     } /*countwindows*/
  977.     
  978.     
  979. boolean resetdirtyscrollbarsvisit (appwindow) hdlappwindow appwindow; {
  980.     
  981.     register hdlappwindow ha = appwindow;
  982.     
  983.     setappwindow (ha);
  984.     
  985.     if ((**ha).flresetscrollbars) {
  986.         
  987.         resetappscrollbars (ha);
  988.         
  989.         (**ha).flresetscrollbars = false; /*consume it*/
  990.         }
  991.     
  992.     return (true); /*visit all open windows*/
  993.     } /*resetdirtyscrollbarsvisit*/
  994.     
  995.     
  996. boolean resetdirtyscrollbars (void) {
  997.  
  998.     visitappwindows (&resetdirtyscrollbarsvisit);
  999.     } /*resetdirtyscrollbars*/
  1000.     
  1001.     
  1002. boolean getuntitledtitle (bs) bigstring bs; {
  1003.     
  1004.     register long ct = 1;
  1005.     hdlappwindow appwindow;
  1006.     
  1007.     while (true) {
  1008.         
  1009.         copystring ("\pUntitled ", bs);
  1010.         
  1011.         pushlong (ct++, bs);
  1012.         
  1013.         if (!findbywindowtitle (bs, &appwindow))
  1014.             return (true);
  1015.         } /*while*/
  1016.     } /*getuntitledtitle*/
  1017.     
  1018.  
  1019. boolean findbyfilevisit (appwindow) hdlappwindow appwindow; {
  1020.     
  1021.     if ((**appwindow).vnum = vnumvisit) {
  1022.     
  1023.         if (equalstrings ((**appwindow).fname, bsvisit)) 
  1024.             return (false);
  1025.         }
  1026.             
  1027.     return (true); /*keep visiting*/
  1028.     } /*findbyfilevisit*/
  1029.     
  1030.     
  1031. boolean findbyfile (bigstring fname, short vnum, hdlappwindow *appwindow) {
  1032.  
  1033.     copystring (fname, bsvisit); /*copy into global so visit routine can access*/
  1034.     
  1035.     vnumvisit = vnum; /*copy into global*/
  1036.     
  1037.     visitappwindows (&findbyfilevisit);
  1038.     
  1039.     if (lastwindowvisited == nil)
  1040.         return (false);
  1041.         
  1042.     *appwindow = lastwindowvisited;
  1043.     
  1044.     return (true);
  1045.     } /*findbyfile*/
  1046.     
  1047.     
  1048. boolean settargetvisit (appwindow) hdlappwindow appwindow; {
  1049.     
  1050.     bigstring bs;
  1051.     
  1052.     getappwindowtitle (appwindow, bs);
  1053.     
  1054.     if (!equalstrings (bsvisit, bs)) /*no match -- keep traversing*/
  1055.         return (true);
  1056.     
  1057.     /*found a match, stop the traversal*/
  1058.     
  1059.     setappwindow (appwindow);
  1060.     
  1061.     return (false); /*stop the traversal*/
  1062.     } /*settargetvisit*/
  1063.     
  1064.     
  1065. boolean setapptarget (bs) bigstring bs; {
  1066.     
  1067.     /*
  1068.     set the globals for the window with the indicated name without bringing
  1069.     the window to the front.
  1070.     */
  1071.     
  1072.     setappwindow (nil);
  1073.     
  1074.     copystring (bs, bsvisit); /*copy into global so visit routine can access*/
  1075.     
  1076.     visitappwindows (&settargetvisit);
  1077.     
  1078.     return (app.appwindow != nil);
  1079.     } /*setapptarget*/    
  1080.     
  1081.  
  1082. boolean setfrontglobalsvisit (appwindow) hdlappwindow appwindow; {
  1083.     
  1084.     setappwindow (appwindow);
  1085.     
  1086.     return (false); /*stop the traversal*/
  1087.     } /*setfrontglobalsvisit*/
  1088.     
  1089.     
  1090. boolean setfrontglobals (void) {
  1091.     
  1092.     setappwindow (nil);
  1093.     
  1094.     visitappwindows (&setfrontglobalsvisit);
  1095.     
  1096.     return (app.appwindow != nil);
  1097.     } /*setfrontglobals*/
  1098.  
  1099.  
  1100. void moveappwindow (hdlappwindow appwindow, Rect r) {
  1101.     
  1102.     register WindowPtr w = (**appwindow).macwindow;
  1103.         
  1104.     constraintodesktop (&r);
  1105.     
  1106.     SizeWindow (w, r.right - r.left, r.bottom - r.top, true);
  1107.     
  1108.     MoveWindow (w, r.left, r.top, false);
  1109.     
  1110.     computewindowinfo (w, appwindow);
  1111.     
  1112.     resizeappscrollbars (appwindow);
  1113.     
  1114.     resetappscrollbars (appwindow);
  1115.     } /*moveappwindow*/
  1116.     
  1117.  
  1118. static void saveappwindowinfo (hdlappwindow appwindow, tydiskwindowinfo *appwindowinfo) {
  1119.     
  1120.     register hdlappwindow ha = appwindow;
  1121.     tydiskwindowinfo x;
  1122.     Rect r;
  1123.     
  1124.     clearbytes (&x, longsizeof (x));
  1125.     
  1126.     x.versionnumber = 1;
  1127.     
  1128.     getdesktoprect (ha, &x.windowrect);
  1129.     
  1130.     getscrollbarinfo ((**ha).vertbar, &x.vertmin, &x.vertmax, &x.vertcurrent);
  1131.     
  1132.     getscrollbarinfo ((**ha).horizbar, &x.horizmin, &x.horizmax, &x.horizcurrent);
  1133.     
  1134.     x.defaultsize = (**ha).defaultsize;
  1135.     
  1136.     x.defaultjustification = (**ha).defaultjustification;
  1137.     
  1138.     diskgetfontname ((**ha).defaultfont, x.defaultfontstring);
  1139.     
  1140.     *appwindowinfo = x;
  1141.     } /*saveappwindowinfo*/
  1142.     
  1143.  
  1144. static void loadappwindowinfo (hdlappwindow appwindow, tydiskwindowinfo appwindowinfo) {
  1145.     
  1146.     register hdlappwindow ha = appwindow;
  1147.     tydiskwindowinfo x = appwindowinfo;
  1148.     short fontnum;
  1149.     
  1150.     moveappwindow (ha, x.windowrect);
  1151.     
  1152.     setscrollbarinfo ((**ha).vertbar, x.vertmin, x.vertmax, x.vertcurrent);
  1153.     
  1154.     setscrollbarinfo ((**ha).horizbar, x.horizmin, x.horizmax, x.horizcurrent);
  1155.     
  1156.     /*
  1157.     (**ha).scrollorigin.v = x.vertcurrent;
  1158.     
  1159.     (**ha).scrollorigin.h = x.horizcurrent;
  1160.     */
  1161.     
  1162.     (**ha).defaultsize = x.defaultsize;
  1163.     
  1164.     (**ha).defaultjustification = x.defaultjustification;
  1165.     
  1166.     diskgetfontnum (x.defaultfontstring, &fontnum);
  1167.     
  1168.     (**ha).defaultfont = fontnum;
  1169.     } /*loadappwindowinfo*/
  1170.     
  1171.  
  1172. boolean savewindow (fname, vnum) bigstring fname; short vnum; {
  1173.     
  1174.     register hdlappwindow ha = app.appwindow;
  1175.     Handle h = nil;
  1176.     long ctbytes;
  1177.     short rnum;
  1178.     
  1179.     setstringlength (bserrorstring, 0);
  1180.     
  1181.     if ((**ha).fnum == 0) { /*file isn't open*/
  1182.     
  1183.         short fnum;
  1184.         
  1185.         if (!filenew (fname, vnum, app.creator, app.filetype, &fnum)) {
  1186.             
  1187.             appalert ("\pError saving the front window.");
  1188.             
  1189.             return (false);
  1190.             }
  1191.         
  1192.         (**ha).fnum = fnum;
  1193.         }
  1194.     else { /*file is already open*/
  1195.         
  1196.         if (!fileseteof ((**ha).fnum, (long) 0)) {
  1197.             
  1198.             appalert ("\pError truncating the file.");
  1199.             
  1200.             return (false);
  1201.             }
  1202.         }
  1203.     
  1204.     if (!(*app.packcallback) (&h)) {
  1205.         
  1206.         appalert ("\pOut of memory.");
  1207.         
  1208.         goto error;
  1209.         }
  1210.             
  1211.     if (!filewritehandle ((**ha).fnum, h)) {
  1212.         
  1213.         appalert ("\pError writing to file.");
  1214.         
  1215.         goto error;
  1216.         }
  1217.     
  1218.     if (openresourcefile (fname, vnum, &rnum)) {
  1219.     
  1220.         tydiskwindowinfo x;
  1221.         Handle hoptions = nil;
  1222.         
  1223.         saveappwindowinfo (ha, &x);
  1224.         
  1225.         putresource (rnum, 'aptk', 128, longsizeof (x), &x);
  1226.         
  1227.         (*app.getoptionscallback) (&hoptions);
  1228.         
  1229.         if (hoptions != nil)
  1230.             putresourcehandle (rnum, 'aptk', 129, hoptions);
  1231.         
  1232.         disposehandle (hoptions);
  1233.         
  1234.         closeresourcefile (rnum);
  1235.         }
  1236.     
  1237.     disposehandle (h);
  1238.     
  1239.     (**ha).flmadechanges = false;
  1240.         
  1241.     return (true);
  1242.         
  1243.     error:
  1244.     
  1245.     disposehandle (h);
  1246.     
  1247.     /*commented dw 8/8/92 -- seems wrong, haven't tested change.
  1248.     
  1249.     fileclose ((**ha).fnum);
  1250.     
  1251.     (**ha).fnum = 0;
  1252.     
  1253.     filedelete (fname, vnum);
  1254.     */
  1255.     
  1256.     return (false);
  1257.     } /*savewindow*/
  1258.     
  1259.  
  1260. boolean newappwindow (bstitle, flshowwindow) bigstring bstitle; boolean flshowwindow; {
  1261.     
  1262.     register hdlappwindow ha = app.appwindow;
  1263.     register WindowPtr macwindow;
  1264.     register short i;
  1265.     register boolean flrelative = false;
  1266.     short hwindow, vwindow;
  1267.     Rect rwindow;
  1268.     bigstring bslastword;
  1269.     hdlscrollbar vertbar = nil, horizbar = nil;
  1270.     boolean fl;
  1271.     
  1272.     if (ha != nil) { /*seed window position from frontmost window*/
  1273.         
  1274.         getdesktoprect (ha, &rwindow);
  1275.         
  1276.         hwindow = rwindow.left + 17;
  1277.         
  1278.         vwindow = rwindow.top + 17;
  1279.                 
  1280.         flrelative = true;
  1281.         }
  1282.         
  1283.     if (!newclearhandle (longsizeof (tyappwindow), (Handle *) &app.appwindow))
  1284.         goto error;
  1285.         
  1286.     ha = app.appwindow; /*copy into register*/    
  1287.  
  1288.     if (app.usecolor && systemhascolor ()) {
  1289.     
  1290.         macwindow = GetNewCWindow (128, nil, (WindowPtr) -1);
  1291.         
  1292.         if (app.exactcolors)
  1293.             getcolorpalette (macwindow);
  1294.         
  1295.         (**ha).flcolorwindow = true;
  1296.         
  1297.         (**ha).forecolor = blackindex;
  1298.         
  1299.         (**ha).backcolor = whiteindex;
  1300.         }
  1301.     else {
  1302.         macwindow = GetNewWindow (128, nil, (WindowPtr) -1);
  1303.         
  1304.         (**ha).flcolorwindow = false;
  1305.         }
  1306.     
  1307.     if (macwindow == nil)
  1308.         goto error;
  1309.     
  1310.     if (app.vertscroll) {
  1311.     
  1312.         if (!newscrollbar (macwindow, true, &vertbar))
  1313.             goto error;
  1314.         }
  1315.         
  1316.     if (app.horizscroll) {
  1317.     
  1318.         if (!newscrollbar (macwindow, false, &horizbar))
  1319.             goto error;
  1320.         }
  1321.         
  1322.     (**ha).vertbar = vertbar;
  1323.     
  1324.     (**ha).horizbar = horizbar;
  1325.         
  1326.     if (flrelative) /*position window relative to previous window*/
  1327.         MoveWindow (macwindow, hwindow, vwindow, false);
  1328.     else
  1329.         centerwindow (macwindow, quickdrawglobal (screenBits).bounds);
  1330.     
  1331.     /*copystring (bstitle, (**ha).fname);*/ /*DW 6/14/92*/
  1332.     
  1333.     if (app.haspalette) {
  1334.         
  1335.         hdlpaletterecord hpal;
  1336.         
  1337.         hpal = newpalette (macwindow, app.ctpaletteicons);
  1338.         
  1339.         if (hpal == nil)
  1340.             goto error;
  1341.             
  1342.         (**ha).hpalette = hpal;
  1343.         }
  1344.     
  1345.     computewindowinfo (macwindow, ha);
  1346.     
  1347.     (**ha).macwindow = macwindow;
  1348.     
  1349.     pushmacport (macwindow);
  1350.     
  1351.     fl = (*app.newrecordcallback) (); /*this callback is allowed to change window size and pos*/
  1352.         
  1353.     popmacport ();
  1354.     
  1355.     if (!fl)
  1356.         goto error;
  1357.         
  1358.     computewindowinfo (macwindow, ha); /*window might have been changed by callback*/
  1359.     
  1360.     (**ha).appdata = app.appdata; /*copy handle alloc'd by newrecord*/
  1361.         
  1362.     (*(WindowPeek) macwindow).refCon = (long) ha;
  1363.     
  1364.     lastword (bstitle, ':', bslastword); /*avoid displaying long paths*/
  1365.     
  1366.     setappwindowtitle (ha, bslastword);
  1367.     
  1368.     (**ha).selectioninfo.fldirty = true;
  1369.     
  1370.     resizeappscrollbars (ha);
  1371.     
  1372.     resetappscrollbars (ha);
  1373.     
  1374.     if (flshowwindow) {
  1375.     
  1376.         showappwindow (ha);
  1377.         
  1378.         showappscrollbars (ha);
  1379.         }
  1380.             
  1381.     return (true);
  1382.     
  1383.     error:
  1384.     
  1385.     if (app.haspalette) 
  1386.         disposepalette ((hdlpaletterecord) (**ha).hpalette);
  1387.     
  1388.     disposescrollbar (vertbar);
  1389.     
  1390.     disposescrollbar (horizbar);
  1391.     
  1392.     macwindow = (**ha).macwindow;
  1393.     
  1394.     if (macwindow != nil)
  1395.         DisposeWindow (macwindow);
  1396.         
  1397.     disposehandle ((Handle) ha);
  1398.     
  1399.     setappwindow (nil);
  1400.     
  1401.     return (false);
  1402.     } /*newappwindow*/
  1403.     
  1404.     
  1405. boolean newuntitledappwindow (boolean flshowwindow) {
  1406.         
  1407.     bigstring bstitle;
  1408.     
  1409.     getuntitledtitle (bstitle);
  1410.     
  1411.     return (newappwindow (bstitle, flshowwindow));
  1412.     } /*newuntitledappwindow*/
  1413.     
  1414.     
  1415. boolean openwindow (fname, vnum) bigstring fname; short vnum; {
  1416.     
  1417.     hdlappwindow appwindow;
  1418.     register hdlappwindow ha;
  1419.     short versionnumber;
  1420.     long ctbytes;
  1421.     short fnum;
  1422.     Handle h;
  1423.     short rnum;
  1424.     Handle hoptions;
  1425.     
  1426.     setstringlength (bserrorstring, 0);
  1427.     
  1428.     if (findbyfile (fname, vnum, &appwindow)) {
  1429.         
  1430.         appalert ("\pThe file is already open.");
  1431.         
  1432.         selectappwindow (appwindow);
  1433.         
  1434.         return (true);
  1435.         }
  1436.     
  1437.     if (!fileopen (fname, vnum, &fnum)) {
  1438.         
  1439.         appalert ("\pError opening the file.");
  1440.         
  1441.         return (false);
  1442.         }
  1443.         
  1444.     if (!filereadwholefile (fnum, &h)) {
  1445.         
  1446.         appalert ("\pError reading from file.");
  1447.         
  1448.         goto error;
  1449.         }
  1450.         
  1451.     /*the data fork of the file stays open while the user is editing it*/
  1452.     
  1453.     if (!newappwindow (fname, false)) {
  1454.         
  1455.         appalert ("\pError creating new window.");
  1456.         
  1457.         goto error;
  1458.         }
  1459.     
  1460.     ha = app.appwindow; /*copy into register*/
  1461.         
  1462.     if (openresourcefile (fname, vnum, &rnum)) {
  1463.         
  1464.         tydiskwindowinfo x;
  1465.         
  1466.         if (getresource (rnum, 'aptk', 128, longsizeof (x), &x))
  1467.             loadappwindowinfo (ha, x); /*resize window, set fields of ha*/
  1468.         
  1469.         getresourcehandle (rnum, 'aptk', 129, &hoptions);
  1470.         
  1471.         closeresourcefile (rnum);
  1472.         }
  1473.     
  1474.     if (!(*app.unpackcallback) (h)) {
  1475.         
  1476.         appalert ("\pError reading from file.");
  1477.         
  1478.         goto error;
  1479.         }
  1480.         
  1481.     if (hoptions != nil) 
  1482.         (*app.putoptionscallback) (hoptions);
  1483.     
  1484.     disposehandle (h);
  1485.     
  1486.     disposehandle (hoptions);
  1487.     
  1488.     (**ha).appdata = app.appdata; /*copy from the app to our record*/
  1489.     
  1490.     (**ha).fnum = fnum;
  1491.     
  1492.     if (vnum == 0) { /*allow caller to give us full path, we maintain it as vnum, fname*/
  1493.         
  1494.         bigstring bs;
  1495.         
  1496.         copystring (fname, bs);
  1497.         
  1498.         pathtofileinfo (bs, fname, &vnum);
  1499.         }
  1500.     
  1501.     if (vnum == 0) { /*DW 6/13/92*/
  1502.     
  1503.         bigstring bs;
  1504.         
  1505.         copystring (fname, bs);
  1506.         
  1507.         pathtofileinfo (bs, fname, &vnum);
  1508.         }
  1509.     
  1510.     copystring (fname, (**ha).fname);
  1511.  
  1512.     (**ha).vnum = vnum;
  1513.     
  1514.     showappwindow (ha);
  1515.     
  1516.     resetappscrollbars (ha);
  1517.     
  1518.     showappscrollbars (ha);
  1519.     
  1520.     invalappwindow (ha, false);
  1521.     
  1522.     return (true);
  1523.     
  1524.     error:
  1525.     
  1526.     disposehandle (h);
  1527.     
  1528.     disposehandle (hoptions);
  1529.     
  1530.     fileclose (fnum);
  1531.     
  1532.     return (false);
  1533.     } /*openwindow*/
  1534.     
  1535.     
  1536. static short appsavedialog (bigstring prompt) {
  1537.  
  1538.     if (!fldialogsenabled) /*don't save changes*/
  1539.         return (2);
  1540.         
  1541.     sysbeep; /*call attention to the user*/
  1542.             
  1543.     return (savedialog (prompt));
  1544.     } /*appsavedialog*/
  1545.     
  1546.     
  1547. boolean closewindow (hdlappwindow appwindow, boolean fldialog) {
  1548.     
  1549.     register hdlappwindow ha = appwindow;
  1550.     
  1551.     if ((**ha).flmadechanges && fldialog && (!app.notsaveable)) {
  1552.         
  1553.         bigstring bs;
  1554.         
  1555.         getappwindowtitle (ha, bs);
  1556.         
  1557.         switch (appsavedialog (bs)) { /*Save “bs” before closing?*/
  1558.             
  1559.             case 1: { /*yes*/
  1560.                 hdlappwindow oldappwindow = app.appwindow;
  1561.                 boolean fl;
  1562.                 
  1563.                 setappwindow (ha);
  1564.                 
  1565.                 fl = savefrontwindow ();
  1566.                 
  1567.                 setappwindow (oldappwindow);
  1568.                 
  1569.                 if (!fl) /*user cancelled save*/
  1570.                     return (false);
  1571.                 
  1572.                 break;
  1573.                 }
  1574.                 
  1575.             case 2: /*no*/
  1576.                 break;
  1577.                 
  1578.             case 3: /*cancel*/
  1579.                 return (false);
  1580.                 
  1581.                 break;
  1582.             } /*switch*/
  1583.         }
  1584.     
  1585.     setappwindow (ha);
  1586.     
  1587.     fileclose ((**ha).fnum); 
  1588.  
  1589.     disposeappwindow (ha);
  1590.     
  1591.     return (true);
  1592.     } /*closewindow*/
  1593.     
  1594.  
  1595. boolean closewindowvisit (appwindow) hdlappwindow appwindow; {
  1596.     
  1597.     return (closewindow (appwindow, true));
  1598.     } /*closewindowvisit*/
  1599.     
  1600.  
  1601. boolean closeallwindows (void) {
  1602.     
  1603.     return (visitappwindows (&closewindowvisit));
  1604.     } /*closeallwindows*/
  1605.  
  1606.     
  1607. static boolean invalallwindowsvisit (appwindow) hdlappwindow appwindow; {
  1608.     
  1609.     invalappwindow (appwindow, false);
  1610.     
  1611.     return (true);
  1612.     } /*invalallwindowsvisit*/
  1613.     
  1614.  
  1615. boolean invalallwindows (void) {
  1616.     
  1617.     return (visitappwindows (&invalallwindowsvisit));
  1618.     } /*invalallwindows*/
  1619.  
  1620.     
  1621. static boolean eraseallwindowsvisit (appwindow) hdlappwindow appwindow; {
  1622.     
  1623.     invalappwindow (appwindow, true);
  1624.     
  1625.     return (true);
  1626.     } /*eraseallwindowsvisit*/
  1627.     
  1628.  
  1629. boolean eraseallwindows (void) {
  1630.     
  1631.     return (visitappwindows (&eraseallwindowsvisit));
  1632.     } /*eraseallwindows*/
  1633.  
  1634.     
  1635. boolean saveaswindow (fname, vnum) bigstring fname; short vnum; {
  1636.     
  1637.     register hdlappwindow ha = app.appwindow;
  1638.  
  1639.     fileclose ((**ha).fnum); /*close the file if it's open*/
  1640.     
  1641.     (**ha).fnum = 0;
  1642.         
  1643.     if (!savewindow (fname, vnum))
  1644.         return (false);
  1645.         
  1646.     copystring (fname, (**ha).fname);
  1647.     
  1648.     (**ha).vnum = vnum;
  1649.     
  1650.     setappwindowtitle (ha, fname);
  1651.     
  1652.     copystring (fname, bstargetwindowname);
  1653.     
  1654.     return (true);
  1655.     } /*saveaswindow*/
  1656.     
  1657.     
  1658. boolean saveasfrontwindow (void) {
  1659.     
  1660.     register hdlappwindow ha = app.appwindow;
  1661.     bigstring fname;
  1662.     short vnum;
  1663.     
  1664.     if ((**ha).fnum == 0)
  1665.         getappwindowtitle (ha, fname);
  1666.     else
  1667.         copystring ((**ha).fname, fname);
  1668.     
  1669.     vnum = (**ha).vnum;
  1670.     
  1671.     if (!sfdialog (true, fname, &vnum, app.filefiltercallback, app.filetype))
  1672.         return (false);
  1673.         
  1674.     return (saveaswindow (fname, vnum));
  1675.     } /*saveasfrontwindow*/
  1676.     
  1677.     
  1678. boolean savefrontwindow (void) {
  1679.     
  1680.     register hdlappwindow ha = app.appwindow;
  1681.     
  1682.     if (ha == nil) /*defensive driving*/
  1683.         return (false);
  1684.     
  1685.     if ((**ha).fnum == 0)
  1686.         return (saveasfrontwindow ());
  1687.         
  1688.     return (savewindow ((**ha).fname, (**ha).vnum));
  1689.     } /*savefrontwindow*/
  1690.     
  1691.     
  1692. boolean closefrontwindow (void) {
  1693.     
  1694.     closewindow (app.appwindow, true);
  1695.     } /*closefrontwindow*/
  1696.     
  1697.  
  1698. boolean openfrontwindow (void) {
  1699.     
  1700.     bigstring fname;
  1701.     short vnum;
  1702.     
  1703.     if (!sfdialog (false, fname, &vnum, app.filefiltercallback, app.filetype))
  1704.         return (false);
  1705.         
  1706.     return (openwindow (fname, vnum));
  1707.     } /*openfrontwindow*/
  1708.     
  1709.     
  1710. boolean revertfrontwindow (void) {
  1711.     
  1712.     hdlappwindow ha = app.appwindow;
  1713.     bigstring fname;
  1714.     short vnum;
  1715.     
  1716.     copystring ((**ha).fname, fname);
  1717.     
  1718.     vnum = (**ha).vnum;
  1719.     
  1720.     if ((**ha).flmadechanges && fldialogsenabled) {
  1721.         
  1722.         bigstring bs, bstitle;
  1723.         
  1724.         sysbeep; /*call attention to the user*/
  1725.             
  1726.         getappwindowtitle (ha, bstitle);
  1727.         
  1728.         copystring ("\pDiscard changes to “", bs);
  1729.         
  1730.         pushstring (bstitle, bs);
  1731.         
  1732.         pushstring ("\p”?", bs);
  1733.         
  1734.         if (!appconfirm (bs))
  1735.             return (false);
  1736.             
  1737.         (**ha).flmadechanges = false; /*avoid dialog in closewindow call*/
  1738.         }
  1739.             
  1740.     if (!closewindow (ha, fldialogsenabled)) /*user declined to discard changes*/
  1741.         return (false);
  1742.         
  1743.     setfrontglobals (); /*seed new window from frontmost window*/
  1744.  
  1745.     return (openwindow (fname, vnum));
  1746.     } /*revertfrontwindow*/
  1747.     
  1748.     
  1749. boolean settargetglobals (void) {
  1750.     
  1751.     /*
  1752.     get ready to do an operation on the target window.  if the name is empty,
  1753.     we do the operation on the frontmost window.
  1754.     
  1755.     the target window name is set using the 'sett' IAC call.
  1756.     
  1757.     return an error to the script if the target window doesn't exist.
  1758.     */
  1759.     
  1760.     if (stringlength (bstargetwindowname) == 0) { /*no target has been established*/
  1761.         
  1762.         if (!setfrontglobals ()) /*no windows are open*/
  1763.             goto error;
  1764.             
  1765.         return (true);
  1766.         }
  1767.         
  1768.     if (!setapptarget (bstargetwindowname)) 
  1769.         goto error;
  1770.         
  1771.     return (true);
  1772.     
  1773.     error:
  1774.     
  1775.     IACreturnerror (nowindowerror, "\pNo window is open.");
  1776.     
  1777.     return (false); /*no window open, stop processing the message*/
  1778.     } /*settargetglobals*/
  1779.     
  1780.     
  1781. boolean exitmainloop (void) {
  1782.     
  1783.     flexitmainloop = closeallwindows ();
  1784.     
  1785.     setfrontglobals (); /*some or all of the windows might now be closed*/
  1786.     
  1787.     return (true);
  1788.     } /*exitmainloop*/
  1789.  
  1790.  
  1791. static void handleupdate (EventRecord ev) {
  1792.     
  1793.     register WindowPtr w = (WindowPtr) ev.message;
  1794.     hdlappwindow appwindow;
  1795.     
  1796.     if (!getwindowrefcon (w, (long *) &appwindow))
  1797.         return;
  1798.     
  1799.     updateappwindow (appwindow);
  1800.     } /*handleupdate*/
  1801.     
  1802.  
  1803. static void handleactivate (EventRecord ev) {
  1804.  
  1805.     register WindowPtr w = (WindowPtr) ev.message;
  1806.     register boolean flactivate = ev.modifiers & activeFlag;
  1807.     hdlappwindow appwindow;
  1808.         
  1809.     if (!getwindowrefcon (w, (long *) &appwindow))
  1810.         return;
  1811.  
  1812.     setappwindow (appwindow);
  1813.  
  1814.     activateappscrollbars (appwindow, flactivate);
  1815.     
  1816.     appprecallback (); 
  1817.  
  1818.     (*app.activatecallback) (flactivate);
  1819.     
  1820.     apppostcallback ();
  1821.     } /*handleactivate*/
  1822.     
  1823.     
  1824. static void handledrag (EventRecord ev, WindowPtr w) {
  1825.     
  1826.     Rect r;
  1827.  
  1828.     r = quickdrawglobal (screenBits).bounds; 
  1829.    
  1830.     r.top = r.top + getmenubarheight (); 
  1831.                
  1832.     r.left = r.left + dragscreenmargin;  
  1833.                
  1834.     r.right = r.right - dragscreenmargin;
  1835.                
  1836.     r.bottom = r.bottom - dragscreenmargin;
  1837.              
  1838.     DragWindow (w, ev.where, &r);   
  1839.     } /*handledrag*/
  1840.     
  1841.     
  1842. static void setappwindowfrommacwindow (WindowPtr macwindow) {
  1843.  
  1844.     hdlappwindow appwindow;
  1845.     
  1846.     if (!getwindowrefcon (macwindow, (long *) &appwindow))
  1847.         return;
  1848.     
  1849.     setappwindow (appwindow);
  1850.     } /*setappwindowfrommacwindow*/
  1851.     
  1852.     
  1853. static void adjustaftergrow (WindowPtr w, Rect oldportrect) {
  1854.     
  1855.     /*
  1856.     8/26/92 DW: optimize. we now ask for the old portrect for the window
  1857.     and only inval any parts of the window that are newly exposed.
  1858.     */
  1859.     
  1860.     hdlappwindow ha;
  1861.     
  1862.     setappwindowfrommacwindow (w);
  1863.  
  1864.     ha = app.appwindow;
  1865.     
  1866.     computewindowinfo (w, ha);
  1867.     
  1868.     appprecallback (); 
  1869.     
  1870.     (*app.windowresizecallback) ();
  1871.     
  1872.     apppostcallback ();
  1873.     
  1874.     invalscrollbar ((**ha).vertbar);
  1875.         
  1876.     invalscrollbar ((**ha).horizbar);
  1877.     
  1878.     resizeappscrollbars (ha);
  1879.     
  1880.     resetappscrollbars (ha);
  1881.     
  1882.     /*smart inval*/ {
  1883.         
  1884.         Rect portrect = (*w).portRect;
  1885.         short scrollbarwidth = getscrollbarwidth ();
  1886.         Rect r;
  1887.         
  1888.         r.left = oldportrect.right;
  1889.         
  1890.         r.right = portrect.right;
  1891.         
  1892.         r.top = oldportrect.top;
  1893.         
  1894.         r.bottom = portrect.bottom;
  1895.         
  1896.         invalrect (r);
  1897.         
  1898.         r.top = oldportrect.bottom;
  1899.         
  1900.         r.bottom = portrect.bottom;
  1901.         
  1902.         r.left = oldportrect.left;
  1903.         
  1904.         r.right = portrect.right;
  1905.         
  1906.         invalrect (r);
  1907.         
  1908.         r = oldportrect;
  1909.         
  1910.         r.left = r.right - scrollbarwidth;
  1911.         
  1912.         r.top = r.bottom - scrollbarwidth;
  1913.         
  1914.         invalrect (r);
  1915.         
  1916.         r = portrect;
  1917.             
  1918.         r.left = r.right - scrollbarwidth;
  1919.         
  1920.         r.top = r.bottom - scrollbarwidth;
  1921.         
  1922.         invalrect (r);
  1923.         
  1924.         /*
  1925.         invalscrollbar ((**ha).vertbar);
  1926.         
  1927.         invalscrollbar ((**ha).horizbar);
  1928.         */
  1929.         
  1930.         updateappscrollbars (ha);
  1931.         }
  1932.     
  1933.     /*invalappwindow (ha, false);*/
  1934.     
  1935.     (**ha).flmadechanges = true; /*we save window size and position*/
  1936.     
  1937.     updateappwindow (ha); /*DW 8/14/92: experiment*/
  1938.     } /*adjustaftergrow*/
  1939.  
  1940.  
  1941. static void handlegrow (Point pt, WindowPtr w) {
  1942.     
  1943.     register long x;
  1944.     Rect boundsrect;
  1945.     Rect r;
  1946.     Rect oldportrect = (*w).portRect;
  1947.     
  1948.     boundsrect.left = minwindowwidth;
  1949.     
  1950.     boundsrect.top = minwindowheight; 
  1951.     
  1952.     r = quickdrawglobal (screenBits).bounds;
  1953.     
  1954.     boundsrect.right = r.right - r.left; /*maximum window width*/
  1955.     
  1956.     boundsrect.bottom = r.bottom - r.top; /*maximum window height*/
  1957.     
  1958.     x = GrowWindow (w, pt, &boundsrect);
  1959.     
  1960.     SizeWindow (w, LoWord (x), HiWord (x), false);
  1961.     
  1962.     if (app.eraseonresize) {
  1963.         
  1964.         Rect r = (*w).portRect;
  1965.         
  1966.         pushmacport (w);
  1967.         
  1968.         pushclip (r);
  1969.         
  1970.         EraseRect (&r);
  1971.         
  1972.         InvalRect (&r);
  1973.         
  1974.         popclip ();
  1975.         
  1976.         popmacport ();
  1977.         }
  1978.     
  1979.     adjustaftergrow (w, oldportrect);
  1980.     } /*handlegrow*/
  1981.     
  1982.  
  1983. void zoomappwindow (hdlappwindow appwindow) {
  1984.     
  1985.     register hdlappwindow ha = appwindow;
  1986.     register WindowPtr w = (**ha).macwindow;
  1987.     register WStateData **hstatedata = (WStateData **) (*(WindowPeek) w).dataHandle;    
  1988.     Rect rzoomed, rcurrent;
  1989.     Rect oldportrect = (*w).portRect;
  1990.     short part;
  1991.     
  1992.     getdesktoprect (ha, &rcurrent);
  1993.     
  1994.     rzoomed = (**hstatedata).stdState; /*default*/
  1995.     
  1996.     if (!optionkeydown ()) { /*allow option key to over-ride "smart" zoom*/
  1997.         
  1998.         boolean fl;
  1999.         
  2000.         appprecallback ();
  2001.         
  2002.         fl = (*app.getcontentsizecallback) ();
  2003.         
  2004.         apppostcallback ();
  2005.         
  2006.         if (fl) {
  2007.             
  2008.             register short height = (**ha).zoomheight;
  2009.             register short width = (**ha).zoomwidth;
  2010.             Rect r;
  2011.             
  2012.             if (app.statuspixels > 0) 
  2013.                 height += app.statuspixels + 3; /*a 3-pixel line separates status & content*/
  2014.             
  2015.             width += (**ha).contentrect.left;
  2016.             
  2017.             /*allow for scrollbars and/or grow icon*/ {
  2018.                 
  2019.                 register short scrollbarwidth = getscrollbarwidth ();
  2020.                 
  2021.                 if (app.horizscroll)
  2022.                     height += scrollbarwidth;
  2023.                 
  2024.                 if (app.vertscroll)
  2025.                     width += scrollbarwidth;
  2026.                 }
  2027.             
  2028.             /*allow for the window's title*/ {
  2029.                 
  2030.                 bigstring bs;
  2031.                 short titlewidth;
  2032.                 
  2033.                 pushstyle (systemFont, 12, normal);
  2034.                 
  2035.                 getappwindowtitle (ha, bs);
  2036.                 
  2037.                 titlewidth = StringWidth (bs) + 64;
  2038.                 
  2039.                 if (width < titlewidth)
  2040.                     width = titlewidth;
  2041.                 
  2042.                 popstyle ();
  2043.                 }
  2044.             
  2045.             if (width < minwindowwidth)
  2046.                 width = minwindowwidth;
  2047.                 
  2048.             if (height < minwindowheight)
  2049.                 height = minwindowheight;
  2050.                 
  2051.             r = rcurrent;
  2052.             
  2053.             r.right = r.left + width;
  2054.             
  2055.             r.bottom = r.top + height;
  2056.             
  2057.             constraintodesktop (&r);
  2058.             
  2059.             rzoomed = r;
  2060.             }
  2061.         }
  2062.  
  2063.     if (equalrects (rzoomed, rcurrent))
  2064.         part = inZoomIn;
  2065.     else {
  2066.         short minscroll, maxscroll, currentscroll;
  2067.         
  2068.         (**hstatedata).stdState = rzoomed;
  2069.         
  2070.         getscrollbarinfo ((**ha).vertbar, &minscroll, &maxscroll, ¤tscroll);
  2071.         
  2072.         setscrollbarcurrent ((**ha).vertbar, minscroll);
  2073.             
  2074.         getscrollbarinfo ((**ha).horizbar, &minscroll, &maxscroll, ¤tscroll);
  2075.         
  2076.         setscrollbarcurrent ((**ha).horizbar, minscroll);
  2077.             
  2078.         appprecallback ();
  2079.         
  2080.         (*app.scrolltocallback) ();
  2081.         
  2082.         apppostcallback ();
  2083.         
  2084.         part = inZoomOut;
  2085.         }
  2086.  
  2087.     /*invalappwindow (ha, app.eraseonresize);*/ /*erase the window contents and inval it*/
  2088.     
  2089.     ZoomWindow (w, part, true);
  2090.     
  2091.     adjustaftergrow (w, oldportrect);
  2092.     } /*zoomappwindow*/
  2093.     
  2094.  
  2095. static void undocommand (void) {
  2096.     } /*undocommand*/
  2097.     
  2098.     
  2099. static boolean pushscrap (Handle h, OSType type) {
  2100.  
  2101.     OSErr ec;
  2102.     
  2103.     if (h == nil)
  2104.         return (true);
  2105.         
  2106.     lockhandle (h);
  2107.     
  2108.     ec = PutScrap (GetHandleSize (h), type, *h);
  2109.     
  2110.     unlockhandle (h);
  2111.     
  2112.     if (ec != noErr) {
  2113.     
  2114.         appalert ("\pError copying to clipboard.");
  2115.         
  2116.         return (false);
  2117.         }
  2118.         
  2119.     return (true);
  2120.     } /*pushscrap*/
  2121.     
  2122.     
  2123. static void copycommand (void) {
  2124.  
  2125.     Handle appscrap = nil, textscrap = nil, pictscrap = nil;
  2126.     boolean flhavescrap = false;
  2127.     OSErr ec;
  2128.     
  2129.     if ((*app.copycallback) (&appscrap))
  2130.         flhavescrap = true;
  2131.     
  2132.     (*app.gettextcallback) (&textscrap); /*textscrap is nil if it failed*/
  2133.     
  2134.     if (textscrap != nil)
  2135.         flhavescrap = true;
  2136.  
  2137.     (*app.getpictcallback) (&pictscrap); /*pictscrap is nil if it failed*/
  2138.     
  2139.     if (pictscrap != nil)
  2140.         flhavescrap = true;
  2141.  
  2142.     if (!flhavescrap) {
  2143.         
  2144.         appalert ("\pNothing to copy.");
  2145.         
  2146.         return;
  2147.         }
  2148.         
  2149.     ZeroScrap ();
  2150.     
  2151.     if (!pushscrap (appscrap, app.creator)) /*error message already set/displayed*/
  2152.         return;
  2153.     
  2154.     if (!pushscrap (textscrap, 'TEXT')) 
  2155.         return;
  2156.     
  2157.     pushscrap (pictscrap, 'PICT');
  2158.     } /*copycommand*/
  2159.     
  2160.     
  2161. static void clearcommand (void) {
  2162.     
  2163.     appprecallback ();
  2164.     
  2165.     (*app.clearcallback) ();
  2166.     
  2167.     apppostcallback ();
  2168.     } /*clearcommand*/
  2169.     
  2170.     
  2171. static void pastecommand (void) {
  2172.     
  2173.     Handle hscrap;
  2174.     long offset, ctbytes;
  2175.     
  2176.     clearcommand ();
  2177.     
  2178.     hscrap = NewHandle (0);
  2179.     
  2180.     ctbytes = GetScrap (hscrap, app.creator, &offset);
  2181.     
  2182.     if (ctbytes > 0) {
  2183.         
  2184.         boolean fl;
  2185.         
  2186.         appprecallback ();
  2187.         
  2188.         fl = (*app.pastecallback) (hscrap);
  2189.         
  2190.         apppostcallback ();
  2191.     
  2192.         if (fl) {
  2193.             
  2194.             DisposeHandle (hscrap);
  2195.             
  2196.             return;
  2197.             }
  2198.             
  2199.         DisposeHandle (hscrap);
  2200.             
  2201.         hscrap = NewHandle (0);
  2202.         }
  2203.     
  2204.     ctbytes = GetScrap (hscrap, 'PICT', &offset);
  2205.     
  2206.     if (ctbytes > 0) {
  2207.         
  2208.         boolean fl;
  2209.         
  2210.         appprecallback ();
  2211.         
  2212.         fl = (*app.putpictcallback) (hscrap);
  2213.         
  2214.         apppostcallback ();
  2215.         
  2216.         if (fl)
  2217.             return;
  2218.             
  2219.         DisposeHandle (hscrap); /*app didn't want the PICT*/
  2220.         
  2221.         hscrap = NewHandle (0);
  2222.         }
  2223.         
  2224.     ctbytes = GetScrap (hscrap, 'TEXT', &offset);
  2225.     
  2226.     if (ctbytes > 0) {
  2227.     
  2228.         boolean fl;
  2229.         
  2230.         appprecallback ();
  2231.         
  2232.         fl = (*app.puttextcallback) (hscrap);
  2233.         
  2234.         apppostcallback ();
  2235.         
  2236.         if (fl)
  2237.             return;
  2238.             
  2239.         DisposeHandle (hscrap);
  2240.             
  2241.         hscrap = NewHandle (0);
  2242.         }
  2243.     
  2244.     if (hscrap != nil)
  2245.         DisposeHandle (hscrap);    
  2246.     } /*pastecommand*/
  2247.     
  2248.     
  2249. static void cutcommand (void) {
  2250.     
  2251.     copycommand ();
  2252.     
  2253.     clearcommand ();
  2254.     } /*cutcommand*/
  2255.     
  2256.     
  2257. static boolean selectallcommand (void) {
  2258.     
  2259.     boolean fl;
  2260.     
  2261.     appprecallback ();
  2262.     
  2263.     fl = (*app.selectallcallback) ();
  2264.     
  2265.     apppostcallback ();
  2266.     
  2267.     return (fl);
  2268.     } /*selectallcommand*/
  2269.     
  2270.  
  2271. static void appsetfont (bigstring fontname) {
  2272.  
  2273.     register hdlappwindow ha = app.appwindow;
  2274.     short fontnumber;
  2275.     
  2276.     GetFNum (fontname, &fontnumber);
  2277.     
  2278.     (**ha).selectioninfo.fontnum = fontnumber;
  2279.     
  2280.     appprecallback (); 
  2281.     
  2282.     (*app.setfontcallback) ();
  2283.     
  2284.     apppostcallback ();
  2285.     
  2286.     (**ha).selectioninfo.fldirty = true;
  2287.     
  2288.     (**ha).defaultfont = fontnumber; /*side-effect, 7/6/92 DW*/
  2289.     } /*appsetfont*/
  2290.             
  2291.     
  2292. static void appsetfontsize (short size) {
  2293.                 
  2294.     register hdlappwindow ha = app.appwindow;
  2295.  
  2296.     (**ha).selectioninfo.fontsize = size;
  2297.     
  2298.     appprecallback (); 
  2299.     
  2300.     (*app.setsizecallback) ();
  2301.     
  2302.     apppostcallback ();
  2303.     
  2304.     (**ha).selectioninfo.fldirty = true;
  2305.     
  2306.     (**ha).defaultsize = size; /*side-effect, 7/6/92 DW*/
  2307.     } /*appsetfontsize*/
  2308.     
  2309.     
  2310. static void handlemenu (long codeword) {
  2311.     
  2312.     register hdlappwindow ha = app.appwindow;
  2313.     register short idmenu, iditem;
  2314.     boolean fl;
  2315.     
  2316.     iditem = LoWord (codeword);
  2317.  
  2318.     if (iditem <= 0)     
  2319.         goto exit;
  2320.      
  2321.     idmenu = HiWord (codeword); 
  2322.     
  2323.     if (SharedMenuHit (idmenu, iditem)) 
  2324.         goto exit;
  2325.     
  2326.     appprecallback (); 
  2327.     
  2328.     fl = (*app.menucallback) (idmenu, iditem);
  2329.     
  2330.     apppostcallback ();
  2331.     
  2332.     if (fl) /*consumed by the app*/
  2333.         goto exit;
  2334.     
  2335.     switch (idmenu) {
  2336.    
  2337.         case applemenu: 
  2338.             switch (iditem) {
  2339.             
  2340.                 case aboutitem:
  2341.                     aboutcommand ();
  2342.                     
  2343.                     break;
  2344.                     
  2345.                 default: {
  2346.                 
  2347.                     bigstring bs;
  2348.                     
  2349.                     GetItem (hdlapplemenu, iditem, bs);
  2350.           
  2351.                     OpenDeskAcc (bs);
  2352.                     
  2353.                     break;
  2354.                     }
  2355.                 } /*switch*/
  2356.             
  2357.             break; /*apple menu*/
  2358.  
  2359.         case filemenu: 
  2360.             switch (iditem) {
  2361.             
  2362.                 case newitem: 
  2363.                     newuntitledappwindow (true);
  2364.                     
  2365.                     break;
  2366.                     
  2367.                 case openitem:
  2368.                     openfrontwindow ();
  2369.                     
  2370.                     break;
  2371.                 
  2372.                 case closeitem:
  2373.                     if (optionkeydown ())
  2374.                         closeallwindows ();
  2375.                     else 
  2376.                         closefrontwindow ();
  2377.                     
  2378.                     break;
  2379.                 
  2380.                 case saveitem: 
  2381.                     savefrontwindow ();
  2382.                     
  2383.                     break;
  2384.                     
  2385.                 case saveasitem:
  2386.                     saveasfrontwindow ();
  2387.                     
  2388.                     break;
  2389.                     
  2390.                 case revertitem:
  2391.                     revertfrontwindow ();
  2392.                     
  2393.                     break;
  2394.                     
  2395.                 case pagesetupitem: 
  2396.                     pagesetup ();
  2397.                     
  2398.                     break;
  2399.                 
  2400.                 case printitem:
  2401.                     printappwindow (ha, true);
  2402.                     
  2403.                     break;
  2404.                     
  2405.                 case quititem:
  2406.                     exitmainloop ();
  2407.                     
  2408.                     break;
  2409.                 } /*switch*/
  2410.             
  2411.             break; /*file menu*/
  2412.             
  2413.         case editmenu: 
  2414.             switch (iditem) {
  2415.                 
  2416.                 case undoitem:
  2417.                     undocommand ();
  2418.                     
  2419.                     break;
  2420.                     
  2421.                 case cutitem:
  2422.                     cutcommand ();
  2423.                     
  2424.                     break;
  2425.                     
  2426.                 case copyitem:
  2427.                     copycommand ();
  2428.                     
  2429.                     break;
  2430.                     
  2431.                 case pasteitem:
  2432.                     pastecommand ();
  2433.                     
  2434.                     break;
  2435.                     
  2436.                 case clearitem:
  2437.                     clearcommand ();
  2438.                     
  2439.                     break;
  2440.                     
  2441.                 case selectallitem:
  2442.                     selectallcommand ();
  2443.                     
  2444.                     break;
  2445.                 } /*switch*/
  2446.                 
  2447.             break; /*edit menu*/
  2448.             
  2449.         case fontmenu: {
  2450.         
  2451.             bigstring bs;
  2452.             
  2453.             getmenuitem (hdlfontmenu, iditem, bs);
  2454.             
  2455.             appsetfont (bs);
  2456.             
  2457.             break;
  2458.             } /*font menu*/
  2459.             
  2460.         case sizemenu: {
  2461.             
  2462.             short size = (**ha).selectioninfo.fontsize;
  2463.             
  2464.             switch (iditem) {
  2465.                 
  2466.                 case point9item:
  2467.                     size = 9;
  2468.                     
  2469.                     break;
  2470.                     
  2471.                 case point10item:
  2472.                     size = 10;
  2473.                     
  2474.                     break;
  2475.                     
  2476.                 case point12item:
  2477.                     size = 12;
  2478.                     
  2479.                     break;
  2480.                     
  2481.                 case point14item:
  2482.                     size = 14;
  2483.                     
  2484.                     break;
  2485.                     
  2486.                 case point18item:
  2487.                     size = 18;
  2488.                     
  2489.                     break;
  2490.                     
  2491.                 case point24item:
  2492.                     size = 24;
  2493.                     
  2494.                     break;
  2495.                     
  2496.                 case point36item:
  2497.                     size = 36;
  2498.                     
  2499.                     break;
  2500.                     
  2501.                 case point48item:
  2502.                     size = 48;
  2503.                     
  2504.                     break;
  2505.                     
  2506.                 case point72item:
  2507.                     size = 72;
  2508.                     
  2509.                     break;
  2510.                     
  2511.                 case pointupitem:
  2512.                     size++;
  2513.                     
  2514.                     break;
  2515.                     
  2516.                 case pointdownitem:
  2517.                     size--;
  2518.                     
  2519.                     if (size < 1)
  2520.                         size = 1;
  2521.                         
  2522.                     break;
  2523.                     
  2524.                 case pointcustomitem: {
  2525.                     bigstring bs;
  2526.                     long num;
  2527.                     
  2528.                     NumToString (size, bs);
  2529.                     
  2530.                     if (!askdialog ("\pCustom font size:", bs))
  2531.                         goto exit;
  2532.                     
  2533.                     StringToNum (bs, &num); /*no protection against non-numeric chars*/
  2534.                     
  2535.                     size = (short) num;
  2536.                     
  2537.                     break;
  2538.                     }
  2539.                 } /*switch*/
  2540.                 
  2541.             if (size != 0) 
  2542.                 appsetfontsize (size);
  2543.                                 
  2544.             break;
  2545.             } /*size menu*/
  2546.             
  2547.         case stylemenu: {
  2548.             
  2549.             tyselectioninfo x = (**ha).selectioninfo;
  2550.             
  2551.             clearbytes (&x, longsizeof (x)); /*init all fields to zero*/
  2552.             
  2553.             x.flplain = false; /*it's off unless plain was selected*/
  2554.             
  2555.             switch (iditem) {
  2556.                 
  2557.                 case plainitem:
  2558.                     x.flplain = true;
  2559.                     
  2560.                     break;
  2561.                     
  2562.                 case bolditem:
  2563.                     x.flbold = true;
  2564.                     
  2565.                     break;
  2566.                     
  2567.                 case italicitem:
  2568.                     x.flitalic = true;
  2569.                     
  2570.                     break;
  2571.                     
  2572.                 case underlineitem:
  2573.                     x.flunderline = true;
  2574.                     
  2575.                     break;
  2576.                     
  2577.                 case outlineitem:
  2578.                     x.floutline = true;
  2579.                     
  2580.                     break;
  2581.                     
  2582.                 case shadowitem:
  2583.                     x.flshadow = true;
  2584.                     
  2585.                     break;
  2586.                 } /*switch*/
  2587.             
  2588.             setselectionstyleinfo (&x, true); /*pack into bits of x.fontstyle*/
  2589.     
  2590.             (**ha).selectioninfo = x;
  2591.             
  2592.             appprecallback (); 
  2593.             
  2594.             (*app.setstylecallback) ();
  2595.             
  2596.             apppostcallback ();
  2597.             
  2598.             (**ha).selectioninfo.fldirty = true;
  2599.             
  2600.             break;
  2601.             } /*style menu*/
  2602.             
  2603.         case justifymenu: {
  2604.             
  2605.             register tyjustification justification = unknownjustification;
  2606.             
  2607.             switch (iditem) {
  2608.                 
  2609.                 case leftjustifyitem:
  2610.                     justification = leftjustified;
  2611.                     
  2612.                     break;
  2613.                     
  2614.                 case centerjustifyitem:
  2615.                     justification = centerjustified;
  2616.                     
  2617.                     break;
  2618.                     
  2619.                 case rightjustifyitem:
  2620.                     justification = rightjustified;
  2621.                     
  2622.                     break;
  2623.                     
  2624.                 case fulljustifyitem:
  2625.                     justification = fulljustified;
  2626.                     
  2627.                     break;
  2628.                     
  2629.                 } /*switch*/
  2630.                 
  2631.             if (justification != unknownjustification) {
  2632.                 
  2633.                 (**ha).selectioninfo.justification = justification;
  2634.                 
  2635.                 appprecallback (); 
  2636.                 
  2637.                 (*app.setjustifycallback) ();
  2638.                 
  2639.                 apppostcallback ();
  2640.                 
  2641.                 (**ha).selectioninfo.fldirty = true;
  2642.                 }
  2643.                 
  2644.             break;
  2645.             } /*justify menu*/
  2646.             
  2647.         } /*switching on which menu was invoked*/
  2648.         
  2649.     exit:
  2650.     
  2651.     HiliteMenu (0);
  2652.     } /*handlemenu*/
  2653.  
  2654.  
  2655. static void handlekeystroke (EventRecord ev) {
  2656.     
  2657.     register char ch = ev.message & charCodeMask;
  2658.     register boolean flcmdkey = ev.modifiers & cmdKey;
  2659.     
  2660.     flcmdperiod = flcmdkey && (ch == '.'); /*set global*/
  2661.     
  2662.     if (SharedScriptRunning ()) { /*cmd-period terminates the script*/
  2663.     
  2664.         if (flcmdperiod) { 
  2665.             
  2666.             CancelSharedScript (); /*cancel the shared menu script, if one is running*/
  2667.         
  2668.             return;
  2669.             }
  2670.         }
  2671.     
  2672.     if (flcmdkey) {
  2673.     
  2674.         handlemenu (MenuKey (ch));
  2675.         
  2676.         return;
  2677.         }
  2678.     
  2679.     setkeyboardstatus (ev); 
  2680.     
  2681.     if (app.appwindow != nil) {
  2682.         
  2683.         appprecallback (); 
  2684.         
  2685.         (*app.keystrokecallback) ();
  2686.         
  2687.         apppostcallback ();
  2688.         }
  2689.     } /*handlekeystroke*/
  2690.     
  2691.     
  2692. static void handlecontent (EventRecord ev, WindowPtr w) {
  2693.     
  2694.     register hdlappwindow ha = app.appwindow;
  2695.     Point pt = ev.where;
  2696.     hdlscrollbar scrollbar;
  2697.     short part;
  2698.         
  2699.     globaltolocalpoint (w, &pt);
  2700.  
  2701.     if (findscrollbar (pt, w, &scrollbar, &part)) { 
  2702.         
  2703.         handlescrollbar (scrollbar == (**ha).vertbar, scrollbar, part, pt);
  2704.         
  2705.         return;
  2706.         }
  2707.         
  2708.     /*send mouse hit to the applet*/
  2709.     
  2710.     mousestatus.localpt = pt;
  2711.     
  2712.     mousestatus.fldoubleclick = mousedoubleclick (ev.where);
  2713.     
  2714.     if (PtInRect (pt, &(**ha).contentrect)) {
  2715.         
  2716.         mousestatus.localpt.h += (**ha).scrollorigin.h;
  2717.     
  2718.         mousestatus.localpt.v += (**ha).scrollorigin.v;
  2719.         
  2720.         setkeyboardstatus (ev); /*applet can tell if shift key is down, other modifiers*/
  2721.     
  2722.         appprecallback (); 
  2723.         
  2724.         (*app.mousecallback) ();
  2725.         
  2726.         apppostcallback ();
  2727.         }
  2728.  
  2729.     if (PtInRect (pt, &(**ha).statusrect)) {
  2730.         
  2731.         pushclip ((**ha).statusrect);
  2732.         
  2733.         (*app.mouseinstatuscallback) ();
  2734.         
  2735.         popclip ();
  2736.         }
  2737.         
  2738.     if (app.haspalette) {
  2739.  
  2740.         if (PtInRect (pt, &(**(**ha).hpalette).r))
  2741.             palettemousedown ((**ha).hpalette);
  2742.         }
  2743.     } /*handlecontent*/
  2744.     
  2745.  
  2746. static void handlemouseup (EventRecord ev) {
  2747.     
  2748.     /*
  2749.     call this when you receive an mouse up event.  if the last mouse down was
  2750.     a double click, we set things up so that the next single click will not
  2751.     be interpreted as a double click.
  2752.     */
  2753.     
  2754.     if (!mousestatus.fldoubleclickdisabled) {
  2755.         
  2756.         mousestatus.mouseuptime = ev.when;
  2757.         
  2758.         mousestatus.mouseuppoint = ev.where;
  2759.         
  2760.         mousestatus.mousedowntime = 0L; /*hasn't happened yet*/
  2761.         }
  2762.     
  2763.     mousestatus.fldoubleclickdisabled = false; /*next mouse up is important*/
  2764.     } /*handlemouseup*/
  2765.  
  2766.  
  2767. static void handlemousedown (EventRecord ev) {
  2768.  
  2769.     short part;
  2770.     WindowPtr w;
  2771.     
  2772.     mousestatus.mousedowntime = ev.when; /*set globals so we can detect a 2click*/
  2773.     
  2774.     mousestatus.mousedownpoint = ev.where;
  2775.     
  2776.       part = FindWindow (ev.where, &w);
  2777.     
  2778.     switch (part) {
  2779.     
  2780.         case inMenuBar: 
  2781.             handlemenu (MenuSelect (ev.where)); 
  2782.             
  2783.             break;
  2784.         
  2785.         case inContent:
  2786.             if (w != nil) {
  2787.             
  2788.                 if (w != FrontWindow ()) { /*just like all other Mac programs*/
  2789.                     
  2790.                     SelectWindow (w);
  2791.                                     
  2792.                     return; /*the mouse click is consumed by the bringtofront operation*/
  2793.                     }    
  2794.                 }
  2795.     
  2796.             handlecontent (ev, w);
  2797.             
  2798.             break;
  2799.         
  2800.         case inSysWindow:
  2801.             SystemClick (&ev, w); 
  2802.             
  2803.             break;
  2804.         
  2805.         case inDrag:
  2806.             handledrag (ev, w);
  2807.             
  2808.             break;
  2809.             
  2810.         case inGrow:
  2811.             handlegrow (ev.where, w);
  2812.             
  2813.             break;
  2814.             
  2815.         case inGoAway:
  2816.             if (TrackGoAway (w, ev.where)) {
  2817.             
  2818.                 if (optionkeydown ())
  2819.                     closeallwindows ();
  2820.                 else
  2821.                     closefrontwindow ();
  2822.                 }
  2823.                 
  2824.             break;
  2825.         
  2826.         case inZoomOut: case inZoomIn:
  2827.             if (TrackBox (w, ev.where, part))
  2828.                 zoomappwindow (app.appwindow);
  2829.             
  2830.             break;
  2831.           
  2832.         } /*switch*/
  2833.     } /*handlemousedown*/
  2834.     
  2835.     
  2836. static boolean jugglervisit (hdlappwindow appwindow) {
  2837.     
  2838.     register hdlappwindow ha = appwindow;
  2839.     register boolean fl = flcurrentlyactive && ((**ha).macwindow == FrontWindow ());
  2840.     
  2841.     setappwindow (ha);
  2842.     
  2843.     activateappscrollbars (ha, fl);
  2844.     
  2845.     appprecallback (); 
  2846.     
  2847.     (*app.activatecallback) (fl);
  2848.     
  2849.     apppostcallback ();
  2850.     
  2851.     drawappgrowicon (ha);
  2852.     } /*jugglervisit*/
  2853.     
  2854.     
  2855. static void handlejuggler (EventRecord ev) {
  2856.     
  2857.     register boolean flresume;
  2858.     tyjugglermessage jmsg;
  2859.     
  2860.     moveleft (&ev.message, &jmsg, longsizeof (jmsg));
  2861.     
  2862.     if (jmsg.eventtype == 1) { /*suspend or resume subevent*/
  2863.         
  2864.         flresume = jmsg.flresume; /*copy into register*/
  2865.         
  2866.         if (jmsg.flconvertclipboard) { /*11/3/91 DW: get to this later*/
  2867.             }
  2868.         
  2869.         appprecallback (); 
  2870.         
  2871.         (*app.resumecallback) (flresume); 
  2872.         
  2873.         apppostcallback ();
  2874.         
  2875.         flcurrentlyactive = flresume; /*set global before visit*/
  2876.         
  2877.         visitappwindows (&jugglervisit); /*send message to all open windows*/
  2878.         }
  2879.     } /*handlejuggler*/
  2880.  
  2881.  
  2882. static boolean handledialogevent (EventRecord event) {
  2883.     
  2884.     /*
  2885.     if the event belongs to a dialog, allow it to be processed in 
  2886.     the standard way. the applet toolkit doesn't currently support the 
  2887.     creation of modeless dialogs, but we must be a host to them anyway.
  2888.     */
  2889.     
  2890.     DialogPtr dlog;
  2891.     short itemnumber;
  2892.     
  2893.     if (!IsDialogEvent (&event)) 
  2894.         return (false);
  2895.     
  2896.     DialogSelect (&event, &dlog, &itemnumber);
  2897.     
  2898.     return (true);
  2899.     } /*handledialogevent*/
  2900.  
  2901.  
  2902. static void handleevent (EventRecord ev) {
  2903.     
  2904.     if (handledialogevent (ev))
  2905.         return;
  2906.     
  2907.     switch (ev.what) {
  2908.     
  2909.         case keyDown: case autoKey: 
  2910.             handlekeystroke (ev);
  2911.             
  2912.             break;
  2913.             
  2914.         case mouseDown:
  2915.             handlemousedown (ev);
  2916.            
  2917.             break;
  2918.             
  2919.         case mouseUp:
  2920.             handlemouseup (ev);
  2921.             
  2922.             break;
  2923.            
  2924.         case activateEvt:
  2925.             handleactivate (ev); 
  2926.            
  2927.             break;
  2928.         
  2929.         case jugglerEvt:
  2930.             handlejuggler (ev);
  2931.             
  2932.             break;
  2933.  
  2934.         case updateEvt:
  2935.             handleupdate (ev);
  2936.            
  2937.             break;
  2938.             
  2939.         case nullEvent:
  2940.             resetdirtyscrollbars ();
  2941.             
  2942.             if (flcurrentlyactive)
  2943.                 CheckSharedMenus (firstsharedmenu); 
  2944.             
  2945.             break;
  2946.             
  2947.         case kHighLevelEvent:
  2948.             AEProcessAppleEvent (&ev);
  2949.             
  2950.             break;
  2951.         } /*switch*/
  2952.     } /*handleevent*/
  2953.     
  2954.  
  2955. static void appidle (void) {
  2956.     
  2957.     appprecallback ();
  2958.     
  2959.     (*app.idlecallback) ();
  2960.     
  2961.     apppostcallback ();
  2962.     } /*appidle*/
  2963.  
  2964.  
  2965. static pascal short appwaitroutine (EventRecord *ev) {
  2966.     
  2967.     /*
  2968.     we're called by the IAC Toolkit while it's waiting for a reply to an 
  2969.     Apple Event. since we may be called while getting new shared menus, we 
  2970.     must not call handleevent for null events here to avoid re-entrancy
  2971.     */
  2972.     
  2973.     if ((*ev).what == nullEvent)
  2974.         appidle ();
  2975.     else
  2976.         handleevent (*ev);
  2977.     
  2978.     return (0);
  2979.     } /*appwaitroutine*/
  2980.  
  2981.  
  2982. boolean maineventhandler (ev) EventRecord ev; {
  2983.     
  2984.     /*
  2985.     if you have an event, and have determined that it's not for you, pass it
  2986.     thru this routine for processing. 
  2987.     
  2988.     we check to see if our Frontier-supplied menus need to be re-installed.  
  2989.     this can happen if a script-writer is making editing changes over in Frontier.  
  2990.     by waiting for real events, we eliminate very annoying delays when editing 
  2991.     in Frontier.
  2992.     
  2993.     returns false if you should break out of your loop, true if you should
  2994.     keep looping.
  2995.     */
  2996.     
  2997.     IACglobals.waitroutine = &appwaitroutine; /*for waiting after sending an Apple Event*/
  2998.     
  2999.     setfrontglobals (); /*event applies to frontmost window*/
  3000.     
  3001.     GetMouse (&mousestatus.localpt);
  3002.     
  3003.     adjustmenus ();
  3004.     
  3005.     appidle ();
  3006.     
  3007.     handleevent (ev); /*might set flexitmainloop true*/
  3008.     
  3009.     return (!flexitmainloop);
  3010.     } /*maineventhandler*/
  3011.  
  3012.  
  3013. void maineventloop (void) {
  3014.     
  3015.     EventRecord ev;
  3016.     
  3017.     while (!flexitmainloop) {
  3018.         
  3019.         WaitNextEvent (everyEvent, &ev, 1, nil);
  3020.         
  3021.         appletevent = ev; /*set global, can be accessed by anyone with an interest*/
  3022.         
  3023.         maineventhandler (ev);
  3024.         } /*while*/
  3025.     } /*maineventloop*/
  3026.  
  3027.  
  3028. boolean serviceeventqueue (void) {
  3029.     
  3030.     /*
  3031.     pop and process all waiting events, return true when we get to a null 
  3032.     event. return false if the user selected the quit command, or otherwise
  3033.     wants the program to terminate.
  3034.     
  3035.     8/8/92 DW: return false also if the user presses cmd-period.
  3036.     */
  3037.     
  3038.     EventRecord ev;
  3039.     
  3040.     flcmdperiod = false;
  3041.     
  3042.     while (!flexitmainloop) {
  3043.         
  3044.         WaitNextEvent (everyEvent, &ev, 1, nil);
  3045.         
  3046.         if (ev.what == nullEvent) /*got all the meaningful events*/
  3047.             return (true);
  3048.         
  3049.         maineventhandler (ev);
  3050.         
  3051.         if (flcmdperiod) {
  3052.             
  3053.             /*sysbeep;*/
  3054.             
  3055.             return (false);
  3056.             }
  3057.         } /*while*/
  3058.         
  3059.     return (false); /*user must have selected the quit command*/
  3060.     } /*serviceeventqueue*/
  3061.  
  3062.  
  3063. static boolean setwindowtitleverb (void) {
  3064.     
  3065.     /*
  3066.     verb that sets the window title of the target window.
  3067.     */
  3068.     
  3069.     bigstring bs;
  3070.     
  3071.     if (!settargetglobals ()) /*this verb requires an open window*/
  3072.         return (false);
  3073.         
  3074.     if (!IACgetstringparam (keyDirectObject, bs))
  3075.         return (false);
  3076.         
  3077.     setappwindowtitle (app.appwindow, bs);
  3078.     
  3079.     copystring (bs, bstargetwindowname);
  3080.         
  3081.     return (IACreturnboolean (true));
  3082.     } /*setwindowtitleverb*/
  3083.     
  3084.     
  3085. static boolean getwindowrectverb (void) { 
  3086.     
  3087.     register hdlappwindow ha = app.appwindow;
  3088.     Rect r = (**app.appwindow).contentrect;
  3089.     
  3090.     OffsetRect (&r, (**ha).scrollorigin.h, (**ha).scrollorigin.v);
  3091.     
  3092.     return (IACreturnrect (&r));
  3093.     } /*getwindowrectverb*/
  3094.     
  3095.     
  3096. static boolean closewindowverb (void) {
  3097.     
  3098.     /*
  3099.     verb that closes an existing window.  it takes no parameters, the
  3100.     current target window is closed.
  3101.     
  3102.     8/25/92 DW: if we close the target window, reset the target to the
  3103.     frontmost window.
  3104.     */
  3105.     
  3106.     boolean fl = false;
  3107.     hdlappwindow ha;
  3108.     boolean flresettarget;
  3109.     
  3110.     flresettarget = stringlength (bstargetwindowname) > 0;
  3111.     
  3112.     if (!settargetglobals ()) /*this verb requires an open window*/
  3113.         return (false);
  3114.     
  3115.     ha = app.appwindow;
  3116.     
  3117.     if (ha != nil) { /*a window is open*/
  3118.     
  3119.         fl = closewindow (ha, fldialogsenabled);
  3120.         
  3121.         if (fl && flresettarget)
  3122.             setstringlength (bstargetwindowname, 0); 
  3123.         }
  3124.         
  3125.     return (IACreturnboolean (fl));
  3126.     } /*closewindowverb*/
  3127.     
  3128.     
  3129. static boolean revertverb (void) {
  3130.     
  3131.     if (!settargetglobals ()) /*this verb requires an open window*/
  3132.         return (false);
  3133.         
  3134.     return (IACreturnboolean (revertfrontwindow ()));
  3135.     } /*revertverb*/
  3136.     
  3137.     
  3138. static boolean zoomwindowverb (void) {
  3139.     
  3140.     if (!settargetglobals ()) /*this verb requires an open window*/
  3141.         return (false);
  3142.         
  3143.     zoomappwindow (app.appwindow);
  3144.         
  3145.     return (IACreturnboolean (true));
  3146.     } /*zoomwindowverb*/
  3147.     
  3148.  
  3149. static boolean scrollwindowverb (void) {
  3150.     
  3151.     short x;
  3152.     tydirection dir;
  3153.     short ct;
  3154.  
  3155.     if (!settargetglobals ()) /*this verb requires an open window*/
  3156.         return (false);
  3157.         
  3158.     if (!IACgetshortparam ('dire', &x))
  3159.         return (false);
  3160.     
  3161.     dir = (tydirection) x;
  3162.     
  3163.     if (!IACgetshortparam ('coun', &ct))
  3164.         return (false);
  3165.         
  3166.     scrollappwindow (dir, false, ct);
  3167.         
  3168.     return (IACreturnboolean (true));
  3169.     } /*scrollwindowverb*/
  3170.     
  3171.     
  3172. static boolean saveasverb (void) {
  3173.     
  3174.     register boolean fl = false;
  3175.     bigstring path;
  3176.     bigstring fname;
  3177.     short vnum;
  3178.     
  3179.     if (!settargetglobals ()) /*this verb requires an open window*/
  3180.         return (false);
  3181.         
  3182.     if (!IACgetstringparam (keyDirectObject, path))
  3183.         return (false);
  3184.         
  3185.     if (stringlength (path) == 0) {
  3186.     
  3187.         fl = savefrontwindow ();
  3188.         }
  3189.     else {
  3190.         if (pathtofileinfo (path, fname, &vnum))
  3191.             fl = saveaswindow (fname, vnum);
  3192.         }
  3193.         
  3194.     return (IACreturnboolean (fl));
  3195.     } /*saveasverb*/
  3196.     
  3197.     
  3198. static boolean openverb (void) {
  3199.     
  3200.     register boolean fl = false;
  3201.     bigstring path;
  3202.     bigstring fname;
  3203.     short vnum;
  3204.     
  3205.     setstringlength (bserrorstring, 0);
  3206.     
  3207.     if (!IACgetstringparam (keyDirectObject, path))
  3208.         return (false);
  3209.     
  3210.     if (!pathtofileinfo (path, fname, &vnum))
  3211.         appalert ("\pError opening the file.");
  3212.     else
  3213.         fl = openwindow (fname, vnum);
  3214.         
  3215.     return (IACreturnboolean (fl));
  3216.     } /*openverb*/
  3217.     
  3218.     
  3219. static boolean nthwindowverb (void) {
  3220.     
  3221.     bigstring bs;
  3222.     short n;
  3223.     hdlappwindow appwindow;
  3224.     
  3225.     if (!IACgetshortparam (keyDirectObject, &n))
  3226.         return (false);
  3227.         
  3228.     findnthwindow (n, &appwindow);
  3229.     
  3230.     getappwindowtitle (appwindow, bs);
  3231.     
  3232.     return (IACreturnstring (bs));
  3233.     } /*nthwindowverb*/
  3234.     
  3235.     
  3236. static boolean selectwindowverb (void) {
  3237.     
  3238.     /*
  3239.     verb that brings a window to the front, you provide the name of the window in 
  3240.     a string parameter.  side effect -- it also sets the target to that window.
  3241.     */
  3242.     
  3243.     register boolean fl = false;
  3244.     bigstring bs;
  3245.     
  3246.     if (!IACgetstringparam (keyDirectObject, bs))
  3247.         return (false);
  3248.         
  3249.     if (selectwindowbytitle (bs)) {
  3250.         
  3251.         fl = true;
  3252.         
  3253.         copystring (bs, bstargetwindowname);
  3254.         }
  3255.         
  3256.     return (IACreturnboolean (fl));
  3257.     } /*selectwindowverb*/
  3258.     
  3259.     
  3260. static boolean perftestverb (void) {
  3261.     
  3262.     /*
  3263.     this verb supports a performance benchmark script written in Frontier.
  3264.     
  3265.     6/28/91 DW: perform rectangle subtraction on two rectangle params,
  3266.     return the difference.
  3267.     */
  3268.     
  3269.     Rect r1, r2, r;
  3270.     
  3271.     if (!IACgetrectparam ('prm1', &r1))
  3272.         return (false);
  3273.         
  3274.     if (!IACgetrectparam ('prm2', &r2))
  3275.         return (false);
  3276.         
  3277.     r.top = r1.top - r2.top;
  3278.     
  3279.     r.left = r1.left - r2.left;
  3280.     
  3281.     r.bottom = r1.bottom - r2.bottom;
  3282.     
  3283.     r.right = r1.right - r2.right;
  3284.     
  3285.     return (IACreturnrect (&r));
  3286.     } /*perftestverb*/
  3287.  
  3288.  
  3289. static boolean alertdialogverb (void) {
  3290.     
  3291.     /*
  3292.     opens up a modal dialog box with the string parameter displayed, wait for
  3293.     the user to click on OK before returning the value.    
  3294.  
  3295.     to support runtime menus, you wire your dialog boxes to IAC events if you want 
  3296.     script writers to be able to transparently talk to the user without Frontier 
  3297.     coming to the front.
  3298.     */
  3299.     
  3300.     bigstring bs;
  3301.     
  3302.     if (!IACgetstringparam (keyDirectObject, bs))
  3303.         return (false);
  3304.         
  3305.     return (IACreturnboolean (appalert (bs)));
  3306.     } /*alertdialogverb*/
  3307.     
  3308.     
  3309. static boolean confirmdialogverb (void) {
  3310.     
  3311.     /*
  3312.     opens up a modal dialog box with the string parameter displayed, wait for
  3313.     the user to click on OK before returning the value.    
  3314.  
  3315.     to support runtime menus, you wire your dialog boxes to IAC events if you want 
  3316.     script writers to be able to transparently talk to the user without Frontier 
  3317.     coming to the front.
  3318.     */
  3319.     
  3320.     bigstring bs;
  3321.     
  3322.     if (!IACgetstringparam (keyDirectObject, bs))
  3323.         return (false);
  3324.         
  3325.     return (IACreturnboolean (appconfirm (bs)));
  3326.     } /*confirmdialogverb*/
  3327.     
  3328.     
  3329. static boolean askdialogverb (void) {
  3330.     
  3331.     /*
  3332.     to support runtime menus, you wire your dialog boxes to IAC events if you want 
  3333.     script writers to be able to transparently talk to the user without Frontier 
  3334.     coming to the front.
  3335.     */
  3336.     
  3337.     bigstring prompt, answer;
  3338.     boolean fl;
  3339.     
  3340.     if (!IACgetstringparam (keyDirectObject, prompt))
  3341.         return (false);
  3342.         
  3343.     if (!IACgetstringparam ('dflt', answer))
  3344.         return (false);
  3345.         
  3346.     fl = appask (prompt, answer);
  3347.         
  3348.     IACglobals.event = IACglobals.reply; /*push the params onto the reply record*/
  3349.     
  3350.     if (!IACpushstringparam (answer, 'ansr'))
  3351.         return (false);
  3352.         
  3353.     return (IACreturnboolean (fl));
  3354.     } /*askdialogverb*/
  3355.  
  3356.     
  3357. static boolean settargetverb (void) {
  3358.     
  3359.     /*
  3360.     set the target of all subsequent verbs to the window named by the string
  3361.     parameter.  
  3362.     
  3363.     special case: set the target string to the empty string if you want verbs 
  3364.     to apply to the frontmost window.
  3365.     
  3366.     returns the title of the target window.
  3367.     */
  3368.     
  3369.     register boolean fl = true;
  3370.     bigstring bs;
  3371.     
  3372.     if (!IACgetstringparam (keyDirectObject, bs))
  3373.         return (false);
  3374.     
  3375.     if (stringlength (bs) == 0) { /*special case*/
  3376.     
  3377.         if (setfrontglobals ())
  3378.             getappwindowtitle (app.appwindow, bs);
  3379.         }
  3380.         
  3381.     else {
  3382.         if (!setapptarget (bs)) 
  3383.             setstringlength (bs, 0);
  3384.         }
  3385.     
  3386.     copystring (bs, bstargetwindowname);
  3387.     
  3388.     return (IACreturnstring (bs));
  3389.     } /*settargetverb*/
  3390.  
  3391.  
  3392. static boolean gettargetverb (void) {
  3393.     
  3394.     /*
  3395.     returns the title of the target window.
  3396.     */
  3397.     
  3398.     bigstring bs;
  3399.     
  3400.     if (!settargetglobals ()) /*this verb requires an open window*/
  3401.         return (false);
  3402.         
  3403.     getappwindowtitle (app.appwindow, bs);
  3404.         
  3405.     return (IACreturnstring (bs));
  3406.     } /*gettargetverb*/
  3407.     
  3408.  
  3409. static boolean newwindowverb (void) {
  3410.     
  3411.     register boolean fl = false;
  3412.     hdlappwindow appwindow;
  3413.     bigstring bs;
  3414.     long ctbars;
  3415.     
  3416.     setstringlength (bserrorstring, 0);
  3417.     
  3418.     if (!IACgetstringparam (keyDirectObject, bs))
  3419.         return (false);
  3420.         
  3421.     if (stringlength (bs) == 0)
  3422.         getuntitledtitle (bs);
  3423.         
  3424.     if (findbywindowtitle (bs, &appwindow)) {
  3425.         
  3426.         appalert ("\pA window with that name is already open.");
  3427.         
  3428.         setstringlength (bs, 0); /*return the empty string to indicate error*/
  3429.         }
  3430.     else {
  3431.         if (newappwindow (bs, true)) {
  3432.             
  3433.             fl = true;
  3434.             
  3435.             copystring (bs, bstargetwindowname);
  3436.             }
  3437.         }
  3438.         
  3439.     return (IACreturnstring (bs));
  3440.     } /*newwindowverb*/
  3441.     
  3442.     
  3443. static boolean madechangesverb (void) {
  3444.  
  3445.     if (!settargetglobals ()) /*this verb requires an open window*/
  3446.         return (false);
  3447.         
  3448.     IACreturnboolean ((**app.appwindow).flmadechanges);
  3449.     } /*madechangesverb*/
  3450.  
  3451.  
  3452. static boolean countwindowsverb (void) {
  3453.  
  3454.     return (IACreturnshort (countwindows ()));
  3455.     } /*countwindowsverb*/
  3456.  
  3457.  
  3458. static boolean selectallverb (void) {
  3459.     
  3460.     register boolean fl;
  3461.     
  3462.     if (!settargetglobals ()) /*this verb requires an open window*/
  3463.         return (false);
  3464.         
  3465.     fl = selectallcommand ();
  3466.     
  3467.     return (IACreturnboolean (fl));
  3468.     } /*selectallverb*/
  3469.  
  3470.  
  3471. static boolean haveselectionverb (void) {
  3472.     
  3473.     register boolean fl;
  3474.     
  3475.     if (!settargetglobals ()) /*this verb requires an open window*/
  3476.         return (false);
  3477.         
  3478.     fl = (*app.haveselectioncallback) ();
  3479.     
  3480.     return (IACreturnboolean (fl));
  3481.     } /*haveselectionverb*/
  3482.  
  3483.  
  3484. static boolean setfontverb (void) {
  3485.     
  3486.     bigstring bs;
  3487.     
  3488.     if (!settargetglobals ()) /*this verb requires an open window*/
  3489.         return (false);
  3490.         
  3491.     if (!IACgetstringparam (keyDirectObject, bs))
  3492.         return (false);
  3493.         
  3494.     appsetfont (bs);
  3495.     
  3496.     return (IACreturnboolean (true));
  3497.     } /*setfontverb*/
  3498.     
  3499.     
  3500. static boolean setfontsizeverb (void) {
  3501.     
  3502.     short fontsize;
  3503.     
  3504.     if (!settargetglobals ()) /*this verb requires an open window*/
  3505.         return (false);
  3506.         
  3507.     if (!IACgetshortparam (keyDirectObject, &fontsize))
  3508.         return (false);
  3509.         
  3510.     appsetfontsize (fontsize);
  3511.     
  3512.     return (IACreturnboolean (true));
  3513.     } /*setfontsizeverb*/
  3514.     
  3515.     
  3516. static boolean printwindowverb (void) {
  3517.  
  3518.     if (!settargetglobals ()) /*this verb requires an open window*/
  3519.         return (false);
  3520.         
  3521.     return (IACreturnboolean (printappwindow (app.appwindow, false)));
  3522.     } /*printwindowverb*/
  3523.  
  3524.  
  3525. static boolean enablealertverb (void) {
  3526.     
  3527.     register boolean fl;
  3528.     Boolean flenabled;
  3529.     
  3530.     if (!IACgetbooleanparam (keyDirectObject, &flenabled))
  3531.         return (false);
  3532.         
  3533.     fl = fldialogsenabled; /*return the original value, per spec*/
  3534.     
  3535.     fldialogsenabled = flenabled;
  3536.     
  3537.     return (IACreturnboolean (fl));
  3538.     } /*enablealertverb*/
  3539.  
  3540.  
  3541. static boolean quitverb (void) {
  3542.     
  3543.     return (IACreturnboolean (exitmainloop ()));
  3544.     } /*quitverb*/
  3545.  
  3546.  
  3547. static boolean geterrorstringverb (void) {
  3548.     
  3549.     return (IACreturnstring (bserrorstring));
  3550.     } /*geterrorstringverb*/
  3551.     
  3552.     
  3553. static boolean movewindowverb (void) {
  3554.     
  3555.     Rect r;
  3556.     WindowPtr w;
  3557.     Rect oldportrect;
  3558.     
  3559.     if (!settargetglobals ()) /*this verb requires an open window*/
  3560.         return (false);
  3561.         
  3562.     w = (**app.appwindow).macwindow;
  3563.  
  3564.     oldportrect = (*w).portRect;
  3565.     
  3566.     if (!IACgetrectparam (keyDirectObject, &r))
  3567.         return (false);
  3568.     
  3569.     moveappwindow (app.appwindow, r);
  3570.     
  3571.     adjustaftergrow (w, oldportrect); 
  3572.         
  3573.     return (IACreturnboolean (true));
  3574.     } /*movewindowverb*/
  3575.     
  3576.     
  3577. static boolean getfilepathverb (void) {
  3578.     
  3579.     register hdlappwindow ha;
  3580.     bigstring path;
  3581.     
  3582.     if (!settargetglobals ()) /*this verb requires an open window*/
  3583.         return (false);
  3584.     
  3585.     ha = app.appwindow;
  3586.     
  3587.     if ((**ha).fnum == 0) /*no file open*/
  3588.         setemptystring (path);
  3589.     else
  3590.         fileinfotopath ((**ha).fname, (**ha).vnum, path);
  3591.     
  3592.     return (IACreturnstring (path));
  3593.     } /*getfilepathverb*/
  3594.     
  3595.     
  3596. static boolean getpictverb (void) {
  3597.  
  3598.     Handle hpict;
  3599.  
  3600.     if (!settargetglobals ()) /*this verb requires an open window*/
  3601.         return (false);
  3602.     
  3603.     hpict = nil;
  3604.     
  3605.     (*app.getpictcallback) (&hpict); /*hpict is nil if it failed*/
  3606.     
  3607.     return (IACreturnbinary (hpict, 'PICT'));
  3608.     } /*getpictverb*/
  3609.  
  3610.  
  3611. static boolean gettextverb (void) {
  3612.  
  3613.     Handle htext;
  3614.  
  3615.     if (!settargetglobals ()) /*this verb requires an open window*/
  3616.         return (false);
  3617.     
  3618.     htext = nil;
  3619.         
  3620.     (*app.gettextcallback) (&htext); /*htext is nil if it failed*/
  3621.     
  3622.     return (IACreturnbinary (htext, 'TEXT'));
  3623.     } /*gettextverb*/
  3624.  
  3625.  
  3626. static boolean putpictverb (void) {
  3627.  
  3628.     Handle hpict;
  3629.     register boolean fl;
  3630.     OSType binarytype;
  3631.  
  3632.     if (!settargetglobals ()) /*this verb requires an open window*/
  3633.         return (false);
  3634.         
  3635.     if (!IACgetbinaryparam (keyDirectObject, &hpict, &binarytype))
  3636.         return (false);
  3637.         
  3638.     fl = (*app.putpictcallback) (hpict); 
  3639.     
  3640.     return (IACreturnboolean (fl));
  3641.     } /*putpictverb*/
  3642.  
  3643.  
  3644. static boolean puttextverb (void) {
  3645.  
  3646.     Handle htext;
  3647.     register boolean fl;
  3648.  
  3649.     if (!settargetglobals ()) /*this verb requires an open window*/
  3650.         return (false);
  3651.         
  3652.     if (!IACgettextparam (keyDirectObject, &htext))
  3653.         return (false);
  3654.         
  3655.     fl = (*app.puttextcallback) (htext);
  3656.     
  3657.     return (IACreturnboolean (fl));
  3658.     } /*puttextverb*/
  3659.  
  3660.  
  3661. static boolean getbinaryverb (void) {
  3662.  
  3663.     AEDesc desc;
  3664.     OSErr ec;
  3665.  
  3666.     if (!settargetglobals ()) /*this verb requires an open window*/
  3667.         return (false);
  3668.     
  3669.     desc.dataHandle = nil;
  3670.     
  3671.     desc.descriptorType = app.filetype;
  3672.     
  3673.     (*app.packcallback) (&desc.dataHandle);
  3674.     
  3675.     ec = AEPutParamDesc (IACglobals.reply, keyDirectObject, &desc);
  3676.     
  3677.     AEDisposeDesc (&desc);
  3678.     
  3679.     return (true);
  3680.     } /*getbinaryverb*/
  3681.  
  3682.  
  3683. static boolean putbinaryverb (void) {
  3684.  
  3685.     AEDesc result;
  3686.     OSErr ec;
  3687.     Handle h;
  3688.     register boolean fl;
  3689.  
  3690.     if (!settargetglobals ()) /*this verb requires an open window*/
  3691.         return (false);
  3692.         
  3693.     ec = AEGetParamDesc (IACglobals.event, keyDirectObject, app.filetype, &result);
  3694.     
  3695.     fl = (*app.unpackcallback) (result.dataHandle); 
  3696.     
  3697.     AEDisposeDesc (&result);
  3698.     
  3699.     return (IACreturnboolean (fl));
  3700.     } /*putbinaryverb*/
  3701.  
  3702.  
  3703. static boolean getpagerectverb (void) {
  3704.     
  3705.     getprintinfo ();
  3706.     
  3707.     return (IACreturnrect (&app.printinfo.paperrect));
  3708.     } /*getpagerectverb*/
  3709.     
  3710.  
  3711. static boolean getwindowposverb (void) {
  3712.     
  3713.     Rect r;
  3714.     
  3715.     if (!settargetglobals ()) /*this verb requires an open window*/
  3716.         return (false);
  3717.         
  3718.     r = (**app.appwindow).windowrect;
  3719.     
  3720.     localtoglobalrect (&r);
  3721.         
  3722.     return (IACreturnrect (&r));
  3723.     } /*getwindowposverb*/
  3724.     
  3725.     
  3726. static pascal OSErr handlecustomverb (AppleEvent *event, AppleEvent *reply, long refcon) {
  3727.  
  3728.     if (SharedScriptCancelled (event, reply)) 
  3729.         return (noErr);
  3730.         
  3731.     IACglobals.event = event; 
  3732.     
  3733.     IACglobals.reply = reply;
  3734.     
  3735.     IACglobals.refcon = refcon;
  3736.     
  3737.     appprecallback ();
  3738.     
  3739.     (*app.iacmessagecallback) ();
  3740.     
  3741.     apppostcallback ();
  3742.     
  3743.     return (noErr);
  3744.     } /*handlecustomverb*/
  3745.  
  3746.  
  3747. static pascal OSErr handlefastverb (AppleEvent *event, AppleEvent *reply, long refcon) {
  3748.     
  3749.     if (SharedScriptCancelled (event, reply)) 
  3750.         return (noErr);
  3751.         
  3752.     IACglobals.event = event; 
  3753.     
  3754.     IACglobals.reply = reply;
  3755.     
  3756.     IACglobals.refcon = refcon;
  3757.     
  3758.     appprecallback ();
  3759.     
  3760.     (*app.iacfastmessagecallback) ();
  3761.     
  3762.     apppostcallback ();
  3763.     
  3764.     return (noErr);
  3765.     } /*handlefastverb*/
  3766.     
  3767.     
  3768. static pascal OSErr handleapp1verb (AppleEvent *event, AppleEvent *reply, long refcon) {
  3769.     
  3770.     /*
  3771.     called by Apple Event Manager when an 'app1' verb arrives.
  3772.     
  3773.     we always return noErr to the Apple Event Manager -- each verb processor
  3774.     may set the error number and string in the reply record by calling 
  3775.     IACreturnerror.
  3776.     */
  3777.     
  3778.     if (SharedScriptCancelled (event, reply)) 
  3779.         return (noErr);
  3780.         
  3781.     IACglobals.event = event; 
  3782.     
  3783.     IACglobals.reply = reply;
  3784.     
  3785.     IACglobals.refcon = refcon;
  3786.         
  3787.     switch (IACgetverbtoken ()) {
  3788.     
  3789.         case newwindowtoken:
  3790.             newwindowverb (); break;
  3791.             
  3792.         case closewindowtoken:
  3793.             closewindowverb (); break;
  3794.         
  3795.         case savewindowtoken:
  3796.             saveasverb (); break;
  3797.             
  3798.         case revertwindowtoken:
  3799.             revertverb (); break;
  3800.             
  3801.         case openwindowtoken:
  3802.             openverb (); break;
  3803.             
  3804.         case gettargettoken:
  3805.             gettargetverb (); break;
  3806.                 
  3807.         case selectwindowtoken:
  3808.             selectwindowverb (); break;
  3809.             
  3810.         case zoomwindowtoken:
  3811.             zoomwindowverb (); break;
  3812.             
  3813.         case scrollwindowtoken:
  3814.             scrollwindowverb (); break;
  3815.             
  3816.         case perftesttoken:
  3817.             perftestverb (); break;
  3818.             
  3819.         case alertdialogtoken:
  3820.             alertdialogverb (); break;
  3821.             
  3822.         case askdialogtoken:
  3823.             askdialogverb (); break;
  3824.             
  3825.         case confirmdialogtoken:
  3826.             confirmdialogverb (); break;
  3827.             
  3828.         case settargettoken:
  3829.             settargetverb (); break;
  3830.             
  3831.         case madechangestoken:
  3832.             madechangesverb (); break;
  3833.             
  3834.         case enabledialogtoken:
  3835.             enablealertverb (); break;
  3836.             
  3837.         case geterrorstringtoken:
  3838.             geterrorstringverb (); break;
  3839.             
  3840.         case nthwindowtoken:
  3841.             nthwindowverb (); break;
  3842.             
  3843.         case getfilepathtoken:
  3844.             getfilepathverb (); break;
  3845.             
  3846.         case movewindowtoken:
  3847.             movewindowverb (); break;
  3848.             
  3849.         case printwindowtoken:
  3850.             printwindowverb (); break;
  3851.             
  3852.         case getpagerecttoken:
  3853.             getpagerectverb (); break;
  3854.             
  3855.         case quittoken:
  3856.             quitverb (); break;
  3857.             
  3858.         case getwindowpostoken:
  3859.             getwindowposverb (); break;
  3860.             
  3861.         case countwindowstoken:
  3862.             countwindowsverb (); break;    
  3863.     
  3864.         case getpicttoken:
  3865.             getpictverb (); break;
  3866.         
  3867.         case gettexttoken:
  3868.             gettextverb (); break;
  3869.             
  3870.         case putpicttoken:
  3871.             putpictverb (); break;
  3872.             
  3873.         case puttexttoken:
  3874.             puttextverb (); break;
  3875.             
  3876.         case selectalltoken:
  3877.             selectallverb (); break;
  3878.             
  3879.         case haveselectiontoken:
  3880.             haveselectionverb (); break;
  3881.             
  3882.         case getwindowrecttoken:
  3883.             getwindowrectverb (); break;
  3884.             
  3885.         case setfonttoken:
  3886.             setfontverb (); break;
  3887.             
  3888.         case setfontsizetoken:
  3889.             setfontsizeverb (); break;
  3890.             
  3891.         case getbinarytoken:
  3892.             getbinaryverb (); break;
  3893.             
  3894.         case putbinarytoken:
  3895.             putbinaryverb (); break;
  3896.             
  3897.         default:
  3898.             IACnothandlederror (); break;
  3899.         } /*switch*/
  3900.         
  3901.     return (noErr);
  3902.     } /*handleapp1verb*/
  3903.     
  3904.  
  3905. static pascal Boolean openfilespec (fs) FSSpec *fs; {
  3906.  
  3907.     bigstring bs;
  3908.     
  3909.     if (!directorytopath ((*fs).parID, (*fs).vRefNum, bs)) 
  3910.         return (false);
  3911.         
  3912.     pushstring ((*fs).name, bs);
  3913.     
  3914.     if ((*app.opendoccallback) (bs)) /*the application handled the opendoc event*/
  3915.         return (true);
  3916.  
  3917.     if (!openwindow (bs, 0)) {
  3918.         
  3919.         IACreturnerror (-1, bserrorstring);
  3920.         
  3921.         return (false);
  3922.         }
  3923.         
  3924.     return (true);
  3925.     } /*openfilespec*/
  3926.     
  3927.  
  3928. static pascal OSErr handleopen (AppleEvent *event, AppleEvent *reply, long refcon) {
  3929.     
  3930.     IACglobals.event = event;
  3931.     
  3932.     IACglobals.reply = reply;
  3933.     
  3934.     IACglobals.refcon = refcon;
  3935.     
  3936.     return (IACdrivefilelist (&openfilespec));
  3937.     } /*handleopen*/
  3938.     
  3939.         
  3940. static pascal Boolean printfilespec (fs) FSSpec *fs; {
  3941.  
  3942.     hdlappwindow appwindow;
  3943.     bigstring fullpath;
  3944.     bigstring fname;
  3945.     short vnum;
  3946.     
  3947.     if (!directorytopath ((*fs).parID, (*fs).vRefNum, fullpath)) 
  3948.         return (false);
  3949.         
  3950.     pushstring ((*fs).name, fullpath);
  3951.  
  3952.     if (!pathtofileinfo (fullpath, fname, &vnum))
  3953.         return (false);
  3954.     
  3955.     if (findbyfile (fname, vnum, &appwindow)) 
  3956.         selectappwindow (appwindow);
  3957.  
  3958.     else {    
  3959.         if (!openwindow (fullpath, 0)) {
  3960.             
  3961.             IACreturnerror (-1, bserrorstring);
  3962.             
  3963.             return (false);
  3964.             }
  3965.         }
  3966.  
  3967.     setfrontglobals (); /*event applies to frontmost window*/
  3968.     
  3969.     return (printappwindow (app.appwindow, false));
  3970.     } /*printfilespec*/
  3971.     
  3972.  
  3973. static pascal OSErr handleprint (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  3974.     
  3975.     IACglobals.event = event;
  3976.     
  3977.     IACglobals.reply = reply;
  3978.     
  3979.     IACglobals.refcon = refcon;
  3980.     
  3981.     return (IACdrivefilelist (&printfilespec));
  3982.     } /*handleprint*/
  3983.     
  3984.         
  3985. static pascal OSErr handlequit (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  3986.     
  3987.     exitmainloop ();
  3988.     
  3989.     return (noErr);
  3990.     } /*handlequit*/
  3991.     
  3992.     
  3993. static pascal OSErr handleopenapp (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  3994.     
  3995.     return (noErr);
  3996.     } /*handleopenapp*/
  3997.     
  3998.     
  3999. pascal Boolean appscriptcomplete (void) {
  4000.     
  4001.     bigstring bs;
  4002.     
  4003.     resetdirtyscrollbars ();
  4004.      
  4005.     if (IACgetstringparam ('errs', bs)) {
  4006.         
  4007.         bigstring bsalert;
  4008.         
  4009.         copystring ("\pError in shared script. ", bsalert);
  4010.         
  4011.         pushstring (bs, bsalert);
  4012.         
  4013.         alertdialog (bsalert);
  4014.         }
  4015.     
  4016.     return (true);
  4017.     } /*appscriptcomplete*/
  4018.     
  4019.     
  4020. static long casereverser (long id) {
  4021.     
  4022.     /*
  4023.     used in setting up the system event handler for the "fast" verbs that the applet
  4024.     implements. we reverse the case of each of the alpha characters in the id. for
  4025.     example, 'DOCS' turns into 'docs'. And 'ƒMnU' turns into 'ƒmNu'. originally we
  4026.     had each applet declare its system handler in the class 'fast', but this wouldn't
  4027.     work if more than one applet was running at a time.
  4028.     */
  4029.  
  4030.     char *p = (char *) &id;
  4031.     short i;
  4032.     
  4033.     for (i = 1; i <= 4; i++) {
  4034.     
  4035.         char ch = *p;
  4036.         
  4037.         if ((ch >= 'a') && (ch <= 'z'))
  4038.             ch -= 32;
  4039.         else
  4040.             if ((ch >= 'A') && (ch <= 'Z'))
  4041.                 ch += 32;
  4042.         
  4043.         *p++ = ch;
  4044.         } /*for*/
  4045.         
  4046.     return (id);
  4047.     } /*casereverser*/
  4048.     
  4049.  
  4050. static boolean initIAC (void) {
  4051.     
  4052.     setstringlength (bstargetwindowname, 0); /*no target window initially*/
  4053.     
  4054.     if (!InitSharedMenus ()) /*initialize the menusharing routines*/
  4055.         return (false);
  4056.         
  4057.     MSglobals.scriptcompletedcallback = (tyMScallback) &appscriptcomplete;
  4058.         
  4059.     if (!IACinstallhandler (app1class, typeWildCard, (ProcPtr) &handleapp1verb))
  4060.         return (false);
  4061.  
  4062.     if (!IACinstallhandler (app.creator, typeWildCard, (ProcPtr) &handlecustomverb))
  4063.         return (false);
  4064.     
  4065.     if (!IACinstallsystemhandler (casereverser (app.creator), typeWildCard, (ProcPtr) &handlefastverb))
  4066.         return (false);
  4067.  
  4068.     if (!IACinstallhandler (kCoreEventClass, kAEOpenApplication, (ProcPtr) &handleopenapp))
  4069.         return (false);
  4070.     
  4071.     if (!IACinstallhandler (kCoreEventClass, kAEOpenDocuments, (ProcPtr) &handleopen))
  4072.         return (false);
  4073.     
  4074.     if (!IACinstallhandler (kCoreEventClass, kAEPrintDocuments, (ProcPtr) &handleprint))
  4075.         return (false);
  4076.     
  4077.     if (!IACinstallhandler (kCoreEventClass, kAEQuitApplication, (ProcPtr) &handlequit))
  4078.         return (false);
  4079.  
  4080.     IACglobals.waitroutine = appwaitroutine;
  4081.     
  4082.     return (true);
  4083.     } /*initIAC*/
  4084.     
  4085.     
  4086. static void initscrap (void) {
  4087.     
  4088.     PScrapStuff x;
  4089.     
  4090.     x = InfoScrap ();
  4091.     
  4092.     if ((*x).scrapState < 0) /*following advice of THINK Reference*/
  4093.         ZeroScrap ();
  4094.     } /*initscrap*/
  4095.     
  4096.  
  4097. static boolean noopcallback (void) {
  4098.     
  4099.     /*sysbeep;*/
  4100.     
  4101.     return (false);
  4102.     } /*noopcallback*/
  4103.     
  4104.     
  4105. static void checkcallback (tyappcallback *cb) {
  4106.     
  4107.     if (*cb == nil) /*the applet doesn't define this callback*/
  4108.         *cb = &noopcallback;
  4109.     } /*checkcallback*/
  4110.     
  4111.     
  4112. static void normaleraserectcallback (Rect r) {
  4113.     
  4114.     EraseRect (&r);
  4115.     } /*normaleraserectcallback*/
  4116.     
  4117.     
  4118. static boolean normalsetfontcallback (void) {
  4119.     
  4120.     hdlappwindow ha = app.appwindow;
  4121.     tyselectioninfo x = (**ha).selectioninfo;
  4122.     
  4123.     if (x.fontnum != -1)
  4124.         (**ha).defaultfont = x.fontnum;
  4125.     
  4126.     if (x.fontsize != -1)
  4127.         (**ha).defaultsize = x.fontsize;
  4128.         
  4129.     invalappwindow (ha, true);
  4130.     
  4131.     return (true);
  4132.     } /*normalsetfontcallback*/
  4133.     
  4134.     
  4135. static void checknilcallbacks (void) {
  4136.     
  4137.     installscroll (); /*install the default handler if appropriate*/
  4138.     
  4139.     checkcallback (&app.newrecordcallback); 
  4140.     
  4141.     checkcallback (&app.disposerecordcallback); 
  4142.     
  4143.     checkcallback (&app.idlecallback); 
  4144.     
  4145.     checkcallback ((tyappcallback *) &app.activatecallback);
  4146.     
  4147.     checkcallback (&app.updatecallback);
  4148.     
  4149.     checkcallback (&app.preupdatecallback);
  4150.     
  4151.     checkcallback (&app.windowresizecallback);
  4152.     
  4153.     checkcallback (&app.iacmessagecallback);
  4154.     
  4155.     checkcallback (&app.iacfastmessagecallback);
  4156.     
  4157.     checkcallback ((tyappcallback *) &app.packcallback);
  4158.     
  4159.     checkcallback ((tyappcallback *) &app.unpackcallback);
  4160.     
  4161.     checkcallback ((tyappcallback *) &app.gettextcallback); 
  4162.     
  4163.     checkcallback ((tyappcallback *) &app.getpictcallback); 
  4164.     
  4165.     checkcallback ((tyappcallback *) &app.scrollcallback); 
  4166.     
  4167.     checkcallback (&app.scrolltocallback); 
  4168.     
  4169.     checkcallback (&app.pagesetupcallback);
  4170.     
  4171.     checkcallback (&app.openprintcallback);
  4172.     
  4173.     checkcallback ((tyappcallback *) &app.printpagecallback);
  4174.     
  4175.     checkcallback (&app.closeprintcallback);
  4176.     
  4177.     checkcallback ((tyappcallback *) &app.puttextcallback);
  4178.     
  4179.     checkcallback ((tyappcallback *) &app.putpictcallback);
  4180.     
  4181.     checkcallback (&app.haveselectioncallback);
  4182.     
  4183.     checkcallback (&app.selectallcallback);
  4184.     
  4185.     checkcallback (&app.keystrokecallback);
  4186.     
  4187.     checkcallback (&app.mousecallback);
  4188.     
  4189.     checkcallback (&app.mouseinstatuscallback);
  4190.     
  4191.     checkcallback (&app.updatestatuscallback);
  4192.     
  4193.     checkcallback ((tyappcallback *) &app.menucallback);
  4194.     
  4195.     checkcallback (&app.insertmenucallback);
  4196.     
  4197.     checkcallback (&app.setselectioninfocallback);
  4198.         
  4199.     if (app.setfontcallback == nil)
  4200.         app.setfontcallback = &normalsetfontcallback;
  4201.     
  4202.     if (app.setsizecallback == nil)
  4203.         app.setsizecallback = &normalsetfontcallback;
  4204.     
  4205.     checkcallback (&app.setstylecallback);
  4206.     
  4207.     checkcallback (&app.setjustifycallback);
  4208.     
  4209.     checkcallback ((tyappcallback *) &app.copycallback);
  4210.         
  4211.     checkcallback (&app.clearcallback);
  4212.     
  4213.     checkcallback ((tyappcallback *) &app.pastecallback);
  4214.     
  4215.     checkcallback (&app.initmacintoshcallback);
  4216.     
  4217.     checkcallback ((tyappcallback *) &app.resumecallback);
  4218.     
  4219.     checkcallback ((tyappcallback *) &app.opendoccallback);
  4220.     
  4221.     if (app.eraserectcallback == nil)
  4222.         app.eraserectcallback = &normaleraserectcallback;
  4223.         
  4224.     checkcallback ((tyappcallback *) &app.getcontentsizecallback);
  4225.     
  4226.     checkcallback ((tyappcallback *) &app.setglobalscallback);
  4227.     
  4228.     checkcallback ((tyappcallback *) &app.getoptionscallback);
  4229.     
  4230.     checkcallback ((tyappcallback *) &app.putoptionscallback);
  4231.     } /*checknilcallbacks*/
  4232.     
  4233.     
  4234. static boolean managersinited = false;
  4235.  
  4236.     
  4237. void appletinitmanagers (void) {
  4238.  
  4239.     initmacintosh ();
  4240.     
  4241.     checknilcallbacks (); /*initmenus uses a callback routine*/
  4242.     
  4243.     initIAC (); 
  4244.         
  4245.     appletheapzone = GetZone ();
  4246.  
  4247.     initmenus ();
  4248.     
  4249.     initscrap ();
  4250.     
  4251.     clearbytes (&mousestatus, longsizeof (mousestatus));
  4252.     
  4253.     (*app.initmacintoshcallback) ();
  4254.     
  4255.     managersinited = true;
  4256.     } /*appletinitmanagers*/
  4257.     
  4258.     
  4259. void runapplet (void) {
  4260.     
  4261.     if (!managersinited) 
  4262.         appletinitmanagers ();
  4263.         
  4264.     maineventloop ();
  4265.     
  4266.     IACremovesystemhandlers ();
  4267.     } /*runapplet*/
  4268.